diff --git a/.circleci/config.yml b/.circleci/config.yml index accd575b3ae..02f2cd8a776 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,20 +4,20 @@ jobs: system-tests: machine: # https://support.circleci.com/hc/en-us/articles/360007324514-How-can-I-use-Docker-volume-mounting-on-CircleCI- - image: ubuntu-2004:current + image: ubuntu-2404:current resource_class: large steps: - checkout - run: - name: Install python 3.9 - command: sudo apt-get install python3.9-venv + name: Install python 3.12 + command: sudo apt-get install python3.12-venv - run: name: versions command: | docker --version - python3.9 --version + python3.12 --version pip --version - run: diff --git a/.dockerignore b/.dockerignore index 73dc2224f1c..c6aa3c66b69 100644 --- a/.dockerignore +++ b/.dockerignore @@ -8,6 +8,7 @@ logs* shell.nix __pycache__ scenario_groups.yml +/binaries/**/.git/config # dotnet **/dotnet/**/bin/ @@ -16,3 +17,4 @@ scenario_groups.yml **/dotnet/**/out/ **/dotnet/**/*.user **/dotnet/**/*.suo +/system-tests.sln diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000..eeee74c9440 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +# default behavior for line endings in text files +* text=auto + +# Set line endings in *.sh files to LF, even on Windows. +# Otherwise, execution within Docker fails on a Windos host. +# See https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings +*.sh text eol=lf + +# Stop hiding directories called "build" in the github file search +# https://docs.github.com/en/search-github/searching-on-github/finding-files-on-github#customizing-excluded-files +build/** linguist-generated=false diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c8cbe1a568b..abb2bf5fe30 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,22 +1,32 @@ * @DataDog/system-tests-core + +/utils/build/docker/cpp/ @DataDog/dd-trace-cpp @DataDog/system-tests-core /utils/build/docker/dotnet*/ @DataDog/apm-dotnet @DataDog/asm-dotnet @DataDog/system-tests-core -/utils/build/docker/golang*/ @DataDog/apm-go @DataDog/system-tests-core +/utils/build/docker/golang*/ @DataDog/dd-trace-go-guild @DataDog/system-tests-core /utils/build/docker/java*/ @DataDog/apm-java @DataDog/asm-java @DataDog/system-tests-core /utils/build/docker/java_otel/ @DataDog/opentelemetry @DataDog/system-tests-core /utils/build/docker/nodejs*/ @DataDog/apm-js @DataDog/asm-js @DataDog/system-tests-core /utils/build/docker/php*/ @DataDog/apm-php @DataDog/system-tests-core /utils/build/docker/python*/ @DataDog/apm-python @DataDog/asm-python @DataDog/system-tests-core -/utils/build/docker/ruby*/ @DataDog/apm-ruby @DataDog/asm-ruby @DataDog/system-tests-core -/parametric/ @Kyle-Verhoog @DataDog/system-tests-core -/tests/parametric/ @Kyle-Verhoog @DataDog/system-tests-core +/utils/build/docker/ruby*/ @DataDog/ruby-guild @DataDog/asm-ruby @DataDog/system-tests-core + +/tests/parametric/ @mabdinur @DataDog/system-tests-core @DataDog/apm-sdk-api /tests/otel_tracing_e2e/ @DataDog/opentelemetry @DataDog/system-tests-core -/tests/remote_config/ @DataDog/system-tests-core @DataDog/remote-config @DataDog/system-tests-core +/tests/remote_config/ @DataDog/remote-config @DataDog/system-tests-core /tests/appsec/ @DataDog/asm-libraries @DataDog/system-tests-core -/manifests/cpp.yml @DataDog/system-tests-core -/manifests/dotnet.yml @DataDog/apm-dotnet @DataDog/asm-dotnet @DataDog/system-tests-core -/manifests/golang.yml @DataDog/dd-trace-go-guild @DataDog/system-tests-core -/manifests/java.yml @DataDog/asm-java @DataDog/apm-java @DataDog/system-tests-core -/manifests/nodejs.yml @DataDog/apm-js @DataDog/asm-js @DataDog/system-tests-core -/manifests/php.yml @DataDog/apm-php @DataDog/asm-php @DataDog/system-tests-core -/manifests/python.yml @DataDog/apm-python @DataDog/asm-python @DataDog/system-tests-core -/manifests/ruby.yml @DataDog/apm-ruby @DataDog/asm-ruby @DataDog/system-tests-core +/tests/debugger/ @DataDog/debugger @DataDog/system-tests-core +/tests/telemetry_intake/ @DataDog/apm-sdk-api @DataDog/system-tests-core +/tests/test_telemetry.py @DataDog/libdatadog-telemetry @DataDog/apm-sdk-api @DataDog/system-tests-core +/tests/serverless @DataDog/serverless @DataDog/system-tests-core + +/manifests/cpp.yml @DataDog/dd-trace-cpp +/manifests/dotnet.yml @DataDog/apm-dotnet @DataDog/asm-dotnet +/manifests/golang.yml @DataDog/dd-trace-go-guild +/manifests/java.yml @DataDog/asm-java @DataDog/apm-java +/manifests/nodejs.yml @DataDog/apm-js @DataDog/asm-js +/manifests/php.yml @DataDog/apm-php @DataDog/asm-php +/manifests/python.yml @DataDog/apm-python @DataDog/asm-python +/manifests/ruby.yml @DataDog/ruby-guild @DataDog/asm-ruby + +# Allows everyone to easily make changes +/tests/telemetry_intake/static/ @DataDog/apm-ecosystems diff --git a/.github/actions/install_runner/action.yaml b/.github/actions/install_runner/action.yaml index 6cd05da1f35..ab0209fec64 100644 --- a/.github/actions/install_runner/action.yaml +++ b/.github/actions/install_runner/action.yaml @@ -1,11 +1,12 @@ name: Install_system_tests_runner description: "Install python virtual env, and system dependencies, using github action cache if possible" + runs: using: composite steps: - uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.12" - uses: actions/cache@v4 id: runner_cache with: diff --git a/.github/actions/lint_code/action.yaml b/.github/actions/lint_code/action.yaml index b7855312e19..04387a699da 100644 --- a/.github/actions/lint_code/action.yaml +++ b/.github/actions/lint_code/action.yaml @@ -26,7 +26,7 @@ runs: node-version: 20 - name: 'Run nodejs lint' shell: bash - working-directory: ./utils/build/docker/nodejs/express4 + working-directory: ./utils/build/docker/nodejs/express run: | npm install npm run lint diff --git a/.github/actions/pull_images/action.yml b/.github/actions/pull_images/action.yml index 7824e01a694..b091a792cd2 100644 --- a/.github/actions/pull_images/action.yml +++ b/.github/actions/pull_images/action.yml @@ -1,51 +1,62 @@ name: "Pull docker images" description: "Pull docker images" inputs: - pull-all: - description: "True to pull all images required for all scenarios" + library: + description: "Which library will be tested (python, cpp, java, ...)" required: true - default: "false" + weblog: + description: "Which weblog will be tested" + required: true + scenarios: + description: "JSON array of scenarios that will be executed" + required: true + cleanup: + description: "Whether to cleanup the disk to free up more space. Should be disabled when a larger machine can be used instead." + required: false + default: "true" + dockerhub_username: + description: "To prevent reaching docker hub API limits, provide a username and token to login to docker hub" + required: false + default: "" + dockerhub_token: + description: "To prevent reaching docker hub API limits, provide a username and token to login to docker hub" + required: false + default: "" + runs: using: composite steps: - - name: Let's free some place + - name: Free some place for scenarios known to require lot of images + if: ${{ (inputs.cleanup == 'true') && (contains(inputs.scenarios, '"INTEGRATIONS"') || contains(inputs.scenarios, '"CROSSED_TRACING_LIBRARIES"')) }} shell: bash run: | - if [[ "${{ inputs.pull-all }}" == "true" ]]; then - df -h + df -h - echo "Removing docker images, dotnet, android, ghc, and CodeQL cache to free space" + echo "Removing docker images, dotnet, android, ghc, and CodeQL cache to free space" - sudo rm -rf /usr/local/lib/android # 9Gb! - sudo rm -rf /opt/hostedtoolcache/CodeQL # 5Gb ! - sudo rm -rf /usr/share/dotnet # 1Gb + sudo rm -rf /usr/local/lib/android # 9Gb! + sudo rm -rf /opt/hostedtoolcache/CodeQL # 5Gb ! + sudo rm -rf /usr/share/dotnet # 1Gb - # sudo docker image prune --all --force # if ever needed, but it's slow. Only 3Gb + # sudo docker image prune --all --force # if ever needed, but it's slow. Only 3Gb - df -h - fi + df -h - - name: Pull images needed for default scenario + - name: Get image list shell: bash run: | - docker pull datadog/system-tests:proxy-v1 || true - docker pull postgres:latest - - name: Pull images needed for all scenarios + source venv/bin/activate + python utils/scripts/get-image-list.py ${{ inputs.library }} ${{ inputs.weblog }} '${{ inputs.scenarios }}' > compose.yaml + env: + PYTHONPATH: "." + + - name: Login to Docker Hub + if: inputs.dockerhub_username != '' && inputs.dockerhub_token != '' + uses: docker/login-action@v3 + with: + username: ${{ inputs.dockerhub_username }} + password: ${{ inputs.dockerhub_token }} + + - name: Pull shell: bash - run: | - if [[ "${{ inputs.pull-all }}" == "true" ]]; then - docker pull mongo:latest - docker pull bitnami/kafka:3.1 - docker pull bitnami/zookeeper:latest - docker pull cassandra:latest - docker pull rabbitmq:3-management-alpine - docker pull mysql/mysql-server:latest - docker pull mcr.microsoft.com/mssql/server:latest - docker pull mcr.microsoft.com/azure-sql-edge:latest - docker pull softwaremill/elasticmq:latest - docker pull datadog/system-tests:python_buddy-v0 - docker pull datadog/system-tests:nodejs_buddy-v0 - docker pull datadog/system-tests:java_buddy-v0 - docker pull datadog/system-tests:ruby_buddy-v0 - docker pull datadog/system-tests:golang_buddy-v0 - fi + run: docker compose pull diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 0db44dd0de6..5a09951d33c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -8,7 +8,6 @@ ## Workflow - 1. ⚠️ Create your PR as draft ⚠️ 2. Work on you PR until the CI passes (if something not related to your task is failing, you can ignore it) 3. Mark it as ready for review @@ -21,7 +20,6 @@ ## Reviewer checklist -* [ ] [Relevant label](https://github.com/DataDog/system-tests/blob/main/docs/CI/labels.md) (`run-parametric-scenario`, `run-profiling-scenario`...) are presents * [ ] If PR title starts with `[]`, double-check that only `` is impacted by the change * [ ] No system-tests internal is modified. Otherwise, I have the approval from [R&P team](https://dd.enterprise.slack.com/archives/C025TJ4RZ8X) * [ ] CI is green, or failing jobs are not related to this change (and you are 100% sure about this statement) @@ -29,4 +27,3 @@ * [ ] the relevant `build-XXX-image` label is present * [ ] A scenario is added (or removed)? * [ ] Get a review from [R&P team](https://dd.enterprise.slack.com/archives/C025TJ4RZ8X) - diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 782b2d7fb27..74e30d667ae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,6 @@ name: Testing the test on: workflow_dispatch: {} - schedule: - - cron: 00 02 * * 2-6 pull_request: branches: @@ -13,10 +11,6 @@ on: - labeled - unlabeled - push: - branches: - - main - concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -47,27 +41,6 @@ jobs: /bin/bash run.sh ++dry APPSEC_SCENARIOS /bin/bash run.sh ++dry TRACER_RELEASE_SCENARIOS - # commenting, as python 3.9 is not available anymore - # test_the_test_platforms: - # strategy: - # matrix: - # os: - # - macos-latest - # name: Test the test (${{ matrix.os }}) - # runs-on: ${{ matrix.os }} - # steps: - # - name: Checkout - # uses: actions/checkout@v4 - # - name: Install runner - # uses: ./.github/actions/install_runner - # # force /bin/bash in order to test against bash 3.2 on macOS - # - name: Test the test (direct) - # run: /bin/bash run.sh TEST_THE_TEST - # - name: Test group parsing - # run: | - # /bin/bash run.sh ++dry APPSEC_SCENARIOS - # /bin/bash run.sh ++dry TRACER_RELEASE_SCENARIOS - scenarios: name: Get scenarios and groups uses: ./.github/workflows/compute-scenarios.yml @@ -89,8 +62,10 @@ jobs: uses: actions/checkout@v4 - name: Get library artifact run: ./utils/scripts/load-binary.sh ${{ matrix.library }} + - name: Get agent artifact run: ./utils/scripts/load-binary.sh agent + # ### appsec-event-rules is now a private repo. The GH_TOKEN provided can't read private repos. # ### skipping this, waiting for a proper solution # - name: Load WAF rules @@ -120,6 +95,9 @@ jobs: - dev fail-fast: false uses: ./.github/workflows/system-tests.yml + permissions: + contents: read + packages: write secrets: inherit with: library: ${{ matrix.library }} @@ -131,6 +109,8 @@ jobs: build_buddies_images: ${{ contains(github.event.pull_request.labels.*.name, 'build-buddies-images') }} build_proxy_image: ${{ contains(github.event.pull_request.labels.*.name, 'build-proxy-image') }} build_lib_injection_app_images: ${{ contains(github.event.pull_request.labels.*.name, 'build-lib-injection-app-images') }} + _experimental_parametric_job_count: ${{ matrix.version == 'dev' && 2 || 1 }} # test both use cases + skip_empty_scenarios: true system_tests_docker_mode: name: Ruby Docker Mode @@ -141,6 +121,8 @@ jobs: - get_dev_artifacts # non official set-up, this needs put this job in last if: contains(needs.impacted_libraries.outputs.impacted_libraries, 'ruby') uses: ./.github/workflows/run-docker-mode.yml + permissions: + packages: write secrets: inherit exotics: @@ -149,6 +131,21 @@ jobs: uses: ./.github/workflows/run-exotics.yml secrets: inherit + fancy-report: + runs-on: ubuntu-latest + needs: + - system_tests + if: always() + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + - run: pip install requests + - run: python utils/scripts/get-workflow-summary.py ${{ github.run_id }} >> $GITHUB_STEP_SUMMARY + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + update-CI-visibility: name: Update CI Visibility Dashboard runs-on: ubuntu-latest diff --git a/.github/workflows/compute-workflow-parameters.yml b/.github/workflows/compute-workflow-parameters.yml new file mode 100644 index 00000000000..7b2ca7fdb2d --- /dev/null +++ b/.github/workflows/compute-workflow-parameters.yml @@ -0,0 +1,82 @@ +name: "Compute workflow, scenarios and weblogs to run" + +on: + workflow_call: + inputs: + library: + description: "Library to run" + required: true + type: string + scenarios: + description: "Comma-separated list of scenarios to run" + type: string + default: "" + scenarios_groups: + description: "Comma-separated list of scenarios groups to run" + type: string + default: "" + _experimental_parametric_job_count: + description: "*EXPERIMENTAL* : How many jobs should be used to run PARAMETRIC scenario" + default: 1 + required: false + type: number + + # Map the workflow outputs to job outputs + outputs: + endtoend_scenarios: + description: "" + value: ${{ jobs.main.outputs.endtoend_scenarios }} + endtoend_weblogs: + description: "" + value: ${{ jobs.main.outputs.endtoend_weblogs }} + graphql_scenarios: + description: "" + value: ${{ jobs.main.outputs.graphql_scenarios }} + graphql_weblogs: + description: "" + value: ${{ jobs.main.outputs.graphql_weblogs }} + libinjection_scenarios: + description: "" + value: ${{ jobs.main.outputs.libinjection_scenarios }} + opentelemetry_scenarios: + description: "" + value: ${{ jobs.main.outputs.opentelemetry_scenarios }} + opentelemetry_weblogs: + description: "" + value: ${{ jobs.main.outputs.opentelemetry_weblogs }} + parametric_scenarios: + description: "" + value: ${{ jobs.main.outputs.parametric_scenarios }} + _experimental_parametric_job_matrix: + description: "" + value: ${{ jobs.main.outputs._experimental_parametric_job_matrix }} + +jobs: + main: + name: Get parameters + runs-on: ubuntu-latest + outputs: + endtoend_scenarios: ${{ steps.main.outputs.endtoend_scenarios }} + endtoend_weblogs: ${{ steps.main.outputs.endtoend_weblogs }} + graphql_scenarios: ${{ steps.main.outputs.graphql_scenarios }} + graphql_weblogs: ${{ steps.main.outputs.graphql_weblogs }} + libinjection_scenarios: ${{ steps.main.outputs.libinjection_scenarios }} + opentelemetry_scenarios: ${{ steps.main.outputs.opentelemetry_scenarios }} + opentelemetry_weblogs: ${{ steps.main.outputs.opentelemetry_weblogs }} + parametric_scenarios: ${{ steps.main.outputs.parametric_scenarios }} + _experimental_parametric_job_matrix: ${{ steps.main.outputs._experimental_parametric_job_matrix }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + repository: 'DataDog/system-tests' + - name: Install runner + uses: ./.github/actions/install_runner + - name: main + id: main + run: | + source venv/bin/activate + python utils/scripts/compute-workflow-parameters.py ${{ inputs.library }} -s "${{ inputs.scenarios }}" -g "${{ inputs.scenarios_groups }}" >> $GITHUB_OUTPUT + env: + PYTHONPATH: "." + _EXPERIMENTAL_PARAMETRIC_JOB_COUNT: ${{ inputs._experimental_parametric_job_count }} diff --git a/.github/workflows/run-docker-mode.yml b/.github/workflows/run-docker-mode.yml index 6636c2067be..45785f2f82b 100644 --- a/.github/workflows/run-docker-mode.yml +++ b/.github/workflows/run-docker-mode.yml @@ -20,6 +20,8 @@ jobs: - name: proxy internal: datadog/system-tests:proxy-v1 runs-on: ubuntu-latest + permissions: + packages: write name: Build (${{ matrix.image.name }}) steps: - name: Checkout @@ -67,11 +69,11 @@ jobs: run: | docker push ${{ env.REPO }}/docker/${{ matrix.image.name }}:g${{ github.sha }} - name: Tag image for release - if: ${{ github.ref == 'refs/heads/master' }} + if: ${{ github.ref == 'refs/heads/main' }} run: docker tag ${{ matrix.image.internal }} ${{ env.REPO }}/docker/${{ matrix.image.name }}:latest - name: Push image for release - if: ${{ github.ref == 'refs/heads/master' }} + if: ${{ github.ref == 'refs/heads/main' }} run: | docker push ${{ env.REPO }}/docker/${{ matrix.image.name }}:latest @@ -98,6 +100,8 @@ jobs: # - rails70 - rails71 runs-on: ubuntu-latest + permissions: + packages: write name: Build (${{ matrix.app }}) steps: - name: Checkout @@ -148,11 +152,11 @@ jobs: run: | docker push ${{ env.REPO }}/docker/${{ matrix.library.name }}/${{ matrix.image }}-${{ matrix.app }}:g${{ github.sha }} - name: Tag image for release - if: ${{ github.ref == 'refs/heads/master' }} + if: ${{ github.ref == 'refs/heads/main' }} run: docker tag system_tests/${{ matrix.image }}:latest ${{ env.REPO }}/docker/${{ matrix.library.name }}/${{ matrix.image }}-${{ matrix.app }}:latest - name: Push image for release - if: ${{ github.ref == 'refs/heads/master' }} + if: ${{ github.ref == 'refs/heads/main' }} run: | docker push ${{ env.REPO }}/docker/${{ matrix.library.name }}/${{ matrix.image }}-${{ matrix.app }}:latest @@ -268,8 +272,6 @@ jobs: docker image list - name: Run scenario run: ./run.sh ++docker ${{ matrix.scenario }} - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Archive logs uses: actions/upload-artifact@v4 if: ${{ always() }} @@ -301,10 +303,10 @@ jobs: if: ${{ always() }} name: Aggregate (${{ matrix.app }}) steps: - - name: Setup python 3.9 + - name: Setup python 3.12 uses: actions/setup-python@v5 with: - python-version: '3.9' + python-version: '3.12' - name: Checkout uses: actions/checkout@v4 with: @@ -315,7 +317,3 @@ jobs: pattern: system-tests-${{ matrix.library }}-${{ matrix.app }}-*-logs-gha${{ github.run_id }}-g${{ github.sha }} merge-multiple: true path: . - - name: Print fancy log report - run: | - find logs* - python utils/scripts/markdown_logs.py >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/run-end-to-end.yml b/.github/workflows/run-end-to-end.yml index bf510554499..1cef0f9aec3 100644 --- a/.github/workflows/run-end-to-end.yml +++ b/.github/workflows/run-end-to-end.yml @@ -47,6 +47,11 @@ on: default: false required: false type: boolean + skip_empty_scenarios: + description: "Skip scenarios that contains only xfail or irrelevant tests" + default: false + required: false + type: boolean env: REGISTRY: ghcr.io @@ -59,10 +64,9 @@ jobs: weblog: ${{ fromJson(inputs.weblogs) }} fail-fast: false env: - TEST_LIBRARY: ${{ inputs.library }} - WEBLOG_VARIANT: ${{ matrix.weblog }} SYSTEM_TESTS_REPORT_ENVIRONMENT: ${{ inputs.ci_environment }} SYSTEM_TESTS_REPORT_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + SYSTEM_TESTS_SKIP_EMPTY_SCENARIO: ${{ inputs.skip_empty_scenarios }} steps: - name: Checkout uses: actions/checkout@v4 @@ -70,10 +74,12 @@ jobs: repository: 'DataDog/system-tests' - name: Install runner uses: ./.github/actions/install_runner - - name: Pull images - uses: ./.github/actions/pull_images + - name: Get binaries artifact + if : ${{ inputs.binaries_artifact != '' }} + uses: actions/download-artifact@v4 with: - pull-all: ${{ contains(inputs.scenarios, '"INTEGRATIONS"') || contains(inputs.scenarios, '"CROSSED_TRACING_LIBRARIES"') }} + name: ${{ inputs.binaries_artifact }} + path: binaries/ - name: Build python's weblog base images if: inputs.library == 'python' && inputs.build_python_base_images run: | @@ -84,12 +90,14 @@ jobs: - name: Build proxy image if: inputs.build_proxy_image run: ./build.sh -i proxy - - name: Get binaries artifact - if : ${{ inputs.binaries_artifact != '' }} - uses: actions/download-artifact@v4 + - name: Pull images + uses: ./.github/actions/pull_images with: - name: ${{ inputs.binaries_artifact }} - path: binaries/ + library: ${{ inputs.library }} + weblog: ${{ matrix.weblog }} + scenarios: ${{ inputs.scenarios }} + dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }} + dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }} - name: Log in to the Container registry if: ${{ inputs.library == 'ruby' }} run: echo ${{ secrets.GITHUB_TOKEN }} | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin @@ -97,32 +105,53 @@ jobs: run: SYSTEM_TEST_BUILD_ATTEMPTS=3 ./build.sh -i agent - name: Build weblog id: build - run: SYSTEM_TEST_BUILD_ATTEMPTS=3 ./build.sh -i weblog + run: SYSTEM_TEST_BUILD_ATTEMPTS=3 ./build.sh ${{ inputs.library }} -i weblog -w ${{ matrix.weblog }} + + - name: Run APPSEC_STANDALONE scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_STANDALONE"') + run: ./run.sh APPSEC_STANDALONE + - name: Run IAST_STANDALONE scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"IAST_STANDALONE"') + run: ./run.sh IAST_STANDALONE + - name: Run SCA_STANDALONE scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"SCA_STANDALONE"') + run: ./run.sh SCA_STANDALONE + - name: Run IAST_DEDUPLICATION scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"IAST_DEDUPLICATION"') + run: ./run.sh IAST_DEDUPLICATION - name: Run DEFAULT scenario - if: steps.build.outcome == 'success' && contains(inputs.scenarios, '"DEFAULT"') + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"DEFAULT"') run: ./run.sh DEFAULT - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} + - name: Run IPV6 scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"IPV6"') && inputs.library != 'ruby' + run: ./run.sh IPV6 - name: Run CROSSED_TRACING_LIBRARIES scenario - if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"CROSSED_TRACING_LIBRARIES"') + if: always() && steps.build.outcome == 'success' && matrix.weblog != 'python3.12' && contains(inputs.scenarios, '"CROSSED_TRACING_LIBRARIES"') run: ./run.sh CROSSED_TRACING_LIBRARIES env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} + SYSTEM_TESTS_AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + SYSTEM_TESTS_AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - name: Run PROFILING scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"PROFILING"') - run: ./run.sh PROFILING + run: | + cat /proc/sys/kernel/perf_event_paranoid + sudo sysctl kernel.perf_event_paranoid=1 + sudo sysctl -p + ./run.sh PROFILING env: DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run TRACE_PROPAGATION_STYLE_W3C scenario - if: always() && steps.build.outcome == 'success' && inputs.library != 'python' && contains(inputs.scenarios, '"TRACE_PROPAGATION_STYLE_W3C"') + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"TRACE_PROPAGATION_STYLE_W3C"') run: ./run.sh TRACE_PROPAGATION_STYLE_W3C - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run INTEGRATIONS scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"INTEGRATIONS"') run: ./run.sh INTEGRATIONS + - name: Run INTEGRATIONS_AWS scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"INTEGRATIONS_AWS"') + run: ./run.sh INTEGRATIONS_AWS env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} + SYSTEM_TESTS_AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + SYSTEM_TESTS_AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - name: Run APM_TRACING_E2E_OTEL scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APM_TRACING_E2E_OTEL"') run: ./run.sh APM_TRACING_E2E_OTEL @@ -133,220 +162,139 @@ jobs: - name: Run LIBRARY_CONF_CUSTOM_HEADER_TAGS scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"LIBRARY_CONF_CUSTOM_HEADER_TAGS"') run: ./run.sh LIBRARY_CONF_CUSTOM_HEADER_TAGS - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run LIBRARY_CONF_CUSTOM_HEADER_TAGS_INVALID scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"LIBRARY_CONF_CUSTOM_HEADER_TAGS_INVALID"') run: ./run.sh LIBRARY_CONF_CUSTOM_HEADER_TAGS_INVALID - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} + - name: Run TRACING_CONFIG_NONDEFAULT scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"TRACING_CONFIG_NONDEFAULT"') + run: ./run.sh TRACING_CONFIG_NONDEFAULT + - name: Run TRACING_CONFIG_NONDEFAULT_2 scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"TRACING_CONFIG_NONDEFAULT_2"') + run: ./run.sh TRACING_CONFIG_NONDEFAULT_2 + - name: Run TRACING_CONFIG_NONDEFAULT_3 scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"TRACING_CONFIG_NONDEFAULT_3"') + run: ./run.sh TRACING_CONFIG_NONDEFAULT_3 - name: Run REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES"') run: ./run.sh REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run REMOTE_CONFIG_MOCKED_BACKEND_LIVE_DEBUGGING scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"REMOTE_CONFIG_MOCKED_BACKEND_LIVE_DEBUGGING"') run: ./run.sh REMOTE_CONFIG_MOCKED_BACKEND_LIVE_DEBUGGING - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run REMOTE_CONFIG_MOCKED_BACKEND_ASM_DD scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"REMOTE_CONFIG_MOCKED_BACKEND_ASM_DD"') run: ./run.sh REMOTE_CONFIG_MOCKED_BACKEND_ASM_DD - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES_NOCACHE scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES_NOCACHE"') run: ./run.sh REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES_NOCACHE - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - - name: Run REMOTE_CONFIG_MOCKED_BACKEND_LIVE_DEBUGGING_NOCACHE scenario - if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"REMOTE_CONFIG_MOCKED_BACKEND_LIVE_DEBUGGING_NOCACHE"') - run: ./run.sh REMOTE_CONFIG_MOCKED_BACKEND_LIVE_DEBUGGING_NOCACHE - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run REMOTE_CONFIG_MOCKED_BACKEND_ASM_DD_NOCACHE scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"REMOTE_CONFIG_MOCKED_BACKEND_ASM_DD_NOCACHE"') run: ./run.sh REMOTE_CONFIG_MOCKED_BACKEND_ASM_DD_NOCACHE - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} + - name: Run AGENT_NOT_SUPPORTING_SPAN_EVENTS scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, 'AGENT_NOT_SUPPORTING_SPAN_EVENTS') && (inputs.library != 'ruby' || matrix.weblog == 'rack') + run: ./run.sh AGENT_NOT_SUPPORTING_SPAN_EVENTS - name: Run APPSEC_MISSING_RULES scenario # C++ 1.2.0 freeze when the rules file is missing if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_MISSING_RULES"') && inputs.library != 'cpp' run: ./run.sh APPSEC_MISSING_RULES - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_CUSTOM_RULES scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_CUSTOM_RULES"') run: ./run.sh APPSEC_CUSTOM_RULES - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_CORRUPTED_RULES scenario # C++ 1.2.0 freeze when the rules file is missing if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_CORRUPTED_RULES"') && inputs.library != 'cpp' run: ./run.sh APPSEC_CORRUPTED_RULES - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_RULES_MONITORING_WITH_ERRORS scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_RULES_MONITORING_WITH_ERRORS"') run: ./run.sh APPSEC_RULES_MONITORING_WITH_ERRORS - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_BLOCKING scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_BLOCKING"') run: ./run.sh APPSEC_BLOCKING - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - - name: Run APPSEC_DISABLED scenario - if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_DISABLED"') - run: ./run.sh APPSEC_DISABLED - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} + - name: Run EVERYTHING_DISABLED scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"EVERYTHING_DISABLED"') + run: ./run.sh EVERYTHING_DISABLED - name: Run APPSEC_LOW_WAF_TIMEOUT scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_LOW_WAF_TIMEOUT"') run: ./run.sh APPSEC_LOW_WAF_TIMEOUT - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_CUSTOM_OBFUSCATION scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_CUSTOM_OBFUSCATION"') run: ./run.sh APPSEC_CUSTOM_OBFUSCATION - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_RATE_LIMITER scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_RATE_LIMITER"') run: ./run.sh APPSEC_RATE_LIMITER - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_BLOCKING_FULL_DENYLIST scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_BLOCKING_FULL_DENYLIST"') run: ./run.sh APPSEC_BLOCKING_FULL_DENYLIST - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_REQUEST_BLOCKING scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_REQUEST_BLOCKING"') run: ./run.sh APPSEC_REQUEST_BLOCKING - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_RUNTIME_ACTIVATION scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_RUNTIME_ACTIVATION"') run: ./run.sh APPSEC_RUNTIME_ACTIVATION - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_WAF_TELEMETRY scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_WAF_TELEMETRY"') run: ./run.sh APPSEC_WAF_TELEMETRY - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_API_SECURITY scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_API_SECURITY"') run: ./run.sh APPSEC_API_SECURITY - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_API_SECURITY_RC scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_API_SECURITY_RC"') run: ./run.sh APPSEC_API_SECURITY_RC - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_API_SECURITY_NO_RESPONSE_BODY scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_API_SECURITY_NO_RESPONSE_BODY"') run: ./run.sh APPSEC_API_SECURITY_NO_RESPONSE_BODY - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_API_SECURITY_WITH_SAMPLING scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_API_SECURITY_WITH_SAMPLING"') run: | ./run.sh APPSEC_API_SECURITY_WITH_SAMPLING cat ./logs_appsec_api_security_with_sampling/tests.log 2>/dev/null | grep "API SECURITY" || true - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_AUTO_EVENTS_EXTENDED scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_AUTO_EVENTS_EXTENDED"') run: ./run.sh APPSEC_AUTO_EVENTS_EXTENDED - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_AUTO_EVENTS_RC scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_AUTO_EVENTS_RC"') run: ./run.sh APPSEC_AUTO_EVENTS_RC - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run APPSEC_RASP scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_RASP"') run: ./run.sh APPSEC_RASP - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - - name: Run APPSEC_STANDALONE scenario - if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_STANDALONE"') - run: ./run.sh APPSEC_STANDALONE - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} + - name: Run APPSEC_META_STRUCT_DISABLED scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"APPSEC_META_STRUCT_DISABLED"') + run: ./run.sh APPSEC_META_STRUCT_DISABLED - name: Run SAMPLING scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"SAMPLING"') run: ./run.sh SAMPLING - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - - name: Run TELEMETRY_APP_STARTED_PRODUCTS_DISABLED scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"TELEMETRY_APP_STARTED_PRODUCTS_DISABLED"') run: ./run.sh TELEMETRY_APP_STARTED_PRODUCTS_DISABLED - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run TELEMETRY_LOG_GENERATION_DISABLED scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"TELEMETRY_LOG_GENERATION_DISABLED"') run: ./run.sh TELEMETRY_LOG_GENERATION_DISABLED - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run TELEMETRY_METRIC_GENERATION_DISABLED scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"TELEMETRY_METRIC_GENERATION_DISABLED"') run: ./run.sh TELEMETRY_METRIC_GENERATION_DISABLED - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run TELEMETRY_METRIC_GENERATION_ENABLED scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"TELEMETRY_METRIC_GENERATION_ENABLED"') run: ./run.sh TELEMETRY_METRIC_GENERATION_ENABLED - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - - name: Run TELEMETRY_DEPENDENCY_LOADED_TEST_FOR_DEPENDENCY_COLLECTION_DISABLED scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"TELEMETRY_DEPENDENCY_LOADED_TEST_FOR_DEPENDENCY_COLLECTION_DISABLED"') run: ./run.sh TELEMETRY_DEPENDENCY_LOADED_TEST_FOR_DEPENDENCY_COLLECTION_DISABLED - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run DEBUGGER_PROBES_STATUS scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"DEBUGGER_PROBES_STATUS"') run: ./run.sh DEBUGGER_PROBES_STATUS - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - - name: Run DEBUGGER_METHOD_PROBES_SNAPSHOT scenario - if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"DEBUGGER_METHOD_PROBES_SNAPSHOT"') - run: ./run.sh DEBUGGER_METHOD_PROBES_SNAPSHOT - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - - name: Run DEBUGGER_LINE_PROBES_SNAPSHOT scenario - if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"DEBUGGER_LINE_PROBES_SNAPSHOT"') - run: ./run.sh DEBUGGER_LINE_PROBES_SNAPSHOT - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - - name: Run DEBUGGER_MIX_LOG_PROBE scenario - if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"DEBUGGER_MIX_LOG_PROBE"') - run: ./run.sh DEBUGGER_MIX_LOG_PROBE - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} + - name: Run DEBUGGER_PROBES_SNAPSHOT scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"DEBUGGER_PROBES_SNAPSHOT"') + run: ./run.sh DEBUGGER_PROBES_SNAPSHOT - name: Run DEBUGGER_PII_REDACTION scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"DEBUGGER_PII_REDACTION"') run: ./run.sh DEBUGGER_PII_REDACTION - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Run DEBUGGER_EXPRESSION_LANGUAGE scenario if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"DEBUGGER_EXPRESSION_LANGUAGE"') run: ./run.sh DEBUGGER_EXPRESSION_LANGUAGE - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - + - name: Run DEBUGGER_EXCEPTION_REPLAY scenario + if: always() && steps.build.outcome == 'success' && contains(inputs.scenarios, '"DEBUGGER_EXCEPTION_REPLAY"') + run: ./run.sh DEBUGGER_EXCEPTION_REPLAY - name: Run all scenarios in replay mode - if: always() && steps.build.outcome == 'success' run: utils/scripts/replay_scenarios.sh env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} DD_APPLICATION_KEY: ${{ secrets.DD_APPLICATION_KEY }} DD_APP_KEY: ${{ secrets.DD_APPLICATION_KEY }} @@ -358,6 +306,7 @@ jobs: if: always() && steps.compress_logs.outcome == 'success' uses: actions/upload-artifact@v4 with: + # log name convention to respect : logs_$SCENARIO-FAMILY_$LIBRARY_$WEBLOG_$CI-ENVIRONMENT name: logs_endtoend_${{ inputs.library }}_${{ matrix.weblog }}_${{ inputs.ci_environment }} path: artifact.tar.gz @@ -375,7 +324,3 @@ jobs: env: FP_API_KEY: ${{ secrets.FP_API_KEY }} FP_IMPORT_URL: ${{ secrets.FP_IMPORT_URL }} - - - name: Print fancy log report - if: ${{ always() }} - run: python utils/scripts/markdown_logs.py >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/run-exotics.yml b/.github/workflows/run-exotics.yml index 6f33dda1738..2cbb0d003f4 100644 --- a/.github/workflows/run-exotics.yml +++ b/.github/workflows/run-exotics.yml @@ -13,10 +13,10 @@ jobs: uses: actions/checkout@v4 with: repository: 'DataDog/system-tests' - - name: Setup python 3.9 + - name: Setup python 3.12 uses: actions/setup-python@v5 with: - python-version: '3.9' + python-version: '3.12' - name: Run run: ./tests/perfs/run.sh golang - name: Display diff --git a/.github/workflows/run-external-processing.yml b/.github/workflows/run-external-processing.yml new file mode 100644 index 00000000000..8a05983e501 --- /dev/null +++ b/.github/workflows/run-external-processing.yml @@ -0,0 +1,79 @@ +name: External-processing tests + +on: + workflow_call: + inputs: + binaries_artifact: + description: "Artifact name containing the binaries to test" + default: '' + required: false + type: string + ci_environment: + description: "Which CI environment is running the tests, used for FPD" + default: 'custom' + required: false + type: string + build_proxy_image: + description: "Shall we build proxy image" + default: false + required: false + type: boolean + +env: + REGISTRY: ghcr.io + + +jobs: + external-processing: + runs-on: + group: "APM Larger Runners" + + env: + SYSTEM_TESTS_REPORT_ENVIRONMENT: ${{ inputs.ci_environment }} + SYSTEM_TESTS_REPORT_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + repository: 'DataDog/system-tests' + - name: Install runner + uses: ./.github/actions/install_runner + + - name: Log in to the Container registry + run: echo ${{ secrets.GITHUB_TOKEN }} | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin + + - name: Get binaries artifact + if : ${{ inputs.binaries_artifact != '' }} + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.binaries_artifact }} + path: binaries/ + + - name: Pull images + uses: ./.github/actions/pull_images + with: + library: golang + weblog: golang-dummy + scenarios: '["EXTERNAL_PROCESSING"]' + + - name: Build proxy image + if: inputs.build_proxy_image + run: ./build.sh -i proxy + + - name: Build agent image + run: ./build.sh -i agent + + - name: Run EXTERNAL_PROCESSING scenario + run: ./run.sh EXTERNAL_PROCESSING + + - name: Compress logs + id: compress_logs + if: always() && steps.build.outcome == 'success' + run: tar -czvf artifact.tar.gz $(ls | grep logs) + - name: Upload artifact + if: always() && steps.compress_logs.outcome == 'success' + uses: actions/upload-artifact@v4 + with: + name: logs_externalprocessing_golang_golang-dummy_${{ inputs.ci_environment }} + path: artifact.tar.gz diff --git a/.github/workflows/run-graphql.yml b/.github/workflows/run-graphql.yml index 7f5ea52424e..263aa1ba8d9 100644 --- a/.github/workflows/run-graphql.yml +++ b/.github/workflows/run-graphql.yml @@ -26,13 +26,18 @@ on: default: 'custom' required: false type: string + skip_empty_scenarios: + description: "Skip scenarios that contains only xfail or irrelevant tests" + default: false + required: false + type: boolean env: REGISTRY: ghcr.io jobs: graphql: - if: inputs.library == 'golang' || inputs.library == 'nodejs' + if: inputs.library == 'golang' || inputs.library == 'nodejs' || inputs.library == 'ruby' runs-on: group: "APM Larger Runners" strategy: @@ -41,10 +46,9 @@ jobs: fail-fast: false env: - TEST_LIBRARY: ${{ inputs.library }} - WEBLOG_VARIANT: ${{ matrix.weblog }} SYSTEM_TESTS_REPORT_ENVIRONMENT: ${{ inputs.ci_environment }} SYSTEM_TESTS_REPORT_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + SYSTEM_TESTS_SKIP_EMPTY_SCENARIO: ${{ inputs.skip_empty_scenarios }} steps: - name: Checkout @@ -72,16 +76,14 @@ jobs: - name: Build weblog id: build - run: SYSTEM_TEST_BUILD_ATTEMPTS=3 ./build.sh -i weblog + run: SYSTEM_TEST_BUILD_ATTEMPTS=3 ./build.sh ${{ inputs.library }} -i weblog -w ${{ matrix.weblog }} - name: Run GRAPHQL_APPSEC scenario run: ./run.sh GRAPHQL_APPSEC - env: - DD_API_KEY: ${{ secrets.DD_API_KEY }} - name: Compress logs id: compress_logs - if: always() + if: always() && steps.build.outcome == 'success' run: tar -czvf artifact.tar.gz $(ls | grep logs) - name: Upload artifact if: always() && steps.compress_logs.outcome == 'success' @@ -94,6 +96,3 @@ jobs: # run: ./utils/scripts/upload_results_CI_visibility.sh dev system-tests ${{ github.run_id }}-${{ github.run_attempt }} # env: # DD_API_KEY: ${{ secrets.DD_CI_API_KEY }} - - name: Print fancy log report - if: always() - run: python utils/scripts/markdown_logs.py >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/run-lib-injection.yml b/.github/workflows/run-lib-injection.yml index c0b70f1e766..be499cd1d82 100644 --- a/.github/workflows/run-lib-injection.yml +++ b/.github/workflows/run-lib-injection.yml @@ -12,6 +12,10 @@ on: description: "Library to test" required: true type: string + version: + description: "Version of the image to test" + required: true + type: string env: REGISTRY: ghcr.io @@ -23,6 +27,8 @@ jobs: outputs: matrix: ${{ steps.compute-matrix.outputs.matrix }} matrix_supported_langs: ${{ steps.compute-matrix.outputs.matrix_supported_langs }} + matrix_profiling_supported: ${{ steps.compute-matrix.outputs.matrix_profiling_supported }} + matrix_skip_basic: ${{ steps.compute-matrix.outputs.matrix_skip_basic }} init_image: ${{ steps.compute-matrix.outputs.init_image }} steps: - name: Compute matrix @@ -36,42 +42,74 @@ jobs: "cpp": [], "dotnet": [{"name":"dd-lib-dotnet-init-test-app","supported":"true"}], "golang": [], - "java": [{"name":"dd-lib-java-init-test-app","supported":"true"},{"name":"jdk7-app","supported":"false"}], + "java": [{"name":"dd-lib-java-init-test-app","supported":"true"}, + {"name":"jdk7-app","supported":"false"}, + {"name":"dd-djm-spark-test-app", "supported":"true", "skip-profiling":"true", "skip-basic":"true"}], "nodejs": [{"name":"sample-app","supported":"true"},{"name":"sample-app-node13","supported":"false"}], "php": [], - "python": [{"name":"dd-lib-python-init-test-django","supported":"true"}, {"name":"dd-lib-python-init-test-django-gunicorn", "supported":"true"}, {"name":"dd-lib-python-init-test-django-uvicorn","supported":"true"}], + "python": [{"name":"dd-lib-python-init-test-django","supported":"true"}, + {"name":"dd-lib-python-init-test-django-gunicorn", "supported":"true"}, + {"name":"dd-lib-python-init-test-django-gunicorn-alpine","supported":"true"}, + {"name":"dd-lib-python-init-test-django-preinstalled","supported":"true","skip-profiling":"true"}, + {"name":"dd-lib-python-init-test-django-unsupported-package-force","supported":"true"}, + {"name":"dd-lib-python-init-test-django-uvicorn","supported":"true"}, + {"name":"dd-lib-python-init-test-protobuf-old","supported":"true"}], "ruby": [{"name":"dd-lib-ruby-init-test-rails","supported":"true"}, {"name":"dd-lib-ruby-init-test-rails-explicit","supported":"true"}, {"name":"dd-lib-ruby-init-test-rails-gemsrb","supported":"true"}] } - init_images={ + prod_init_images={ "cpp": [], - "dotnet": ["gcr.io/datadoghq/dd-lib-dotnet-init:latest","ghcr.io/datadog/dd-trace-dotnet/dd-lib-dotnet-init:latest_snapshot"], + "dotnet": ["gcr.io/datadoghq/dd-lib-dotnet-init:latest"], "golang": [], - "java": ["gcr.io/datadoghq/dd-lib-java-init:latest","ghcr.io/datadog/dd-trace-java/dd-lib-java-init:latest_snapshot"], - "nodejs": ["gcr.io/datadoghq/dd-lib-js-init:latest","ghcr.io/datadog/dd-trace-js/dd-lib-js-init:latest_snapshot"], + "java": ["gcr.io/datadoghq/dd-lib-java-init:latest"], + "nodejs": ["gcr.io/datadoghq/dd-lib-js-init:latest"], "php": [], - "python": ["gcr.io/datadoghq/dd-lib-python-init:latest","ghcr.io/datadog/dd-trace-py/dd-lib-python-init:latest_snapshot"], - "ruby": ["gcr.io/datadoghq/dd-lib-ruby-init:latest","ghcr.io/datadog/dd-trace-rb/dd-lib-ruby-init:latest_snapshot"], + "python": ["gcr.io/datadoghq/dd-lib-python-init:latest"], + "ruby": ["gcr.io/datadoghq/dd-lib-ruby-init:latest"], + } + + dev_init_images={ + "cpp": [], + "dotnet": ["ghcr.io/datadog/dd-trace-dotnet/dd-lib-dotnet-init:latest_snapshot"], + "golang": [], + "java": ["ghcr.io/datadog/dd-trace-java/dd-lib-java-init:latest_snapshot"], + "nodejs": ["ghcr.io/datadog/dd-trace-js/dd-lib-js-init:latest_snapshot"], + "php": [], + "python": ["ghcr.io/datadog/dd-trace-py/dd-lib-python-init:latest_snapshot"], + "ruby": ["ghcr.io/datadog/dd-trace-rb/dd-lib-ruby-init:latest_snapshot"], } #All weblog variants result = weblogs["${{ inputs.library }}"] - #Only supported weblog variants results_supported_langs = [] + results_profiling_supported = [] + results_skip_basic = [] for weblog in weblogs["${{ inputs.library }}"]: if weblog["supported"] == "true": results_supported_langs.append(weblog["name"]) + if "skip-profiling" not in weblog or weblog["skip-profiling"] != "true": + results_profiling_supported.append(weblog["name"]) + if "skip-basic" in weblog and weblog["skip-basic"] == "true": + results_skip_basic.append(weblog["name"]) - result_init_image = init_images["${{ inputs.library }}"] + #Use the latest init image for prod version, latest_snapshot init image for dev version + if "${{ inputs.version }}" == 'prod': + result_init_image = prod_init_images["${{ inputs.library }}"] + else: + result_init_image = dev_init_images["${{ inputs.library }}"] with open(os.environ['GITHUB_OUTPUT'], 'a') as fh: print(f'matrix={json.dumps(result)}', file=fh) print(f'init_image={json.dumps(result_init_image)}', file=fh) print(f'matrix_supported_langs={json.dumps(results_supported_langs)}', file=fh) + print(f'matrix_profiling_supported={json.dumps(results_profiling_supported)}', file=fh) + print(f'matrix_skip_basic={json.dumps(results_skip_basic)}', file=fh) print(json.dumps(result, indent=2)) print(json.dumps(result_init_image, indent=2)) print(json.dumps(results_supported_langs, indent=2)) + print(json.dumps(results_profiling_supported, indent=2)) + print(json.dumps(results_skip_basic, indent=2)) lib-injection-init-image-validator: if: inputs.library == 'dotnet' || inputs.library == 'java' || inputs.library == 'python' || inputs.library == 'ruby' || inputs.library == 'nodejs' @@ -86,6 +124,8 @@ jobs: matrix: weblog: ${{ fromJson(needs.compute-matrix.outputs.matrix) }} lib_init_image: ${{ fromJson(needs.compute-matrix.outputs.init_image) }} + exclude: + - weblog: {"name":"dd-djm-spark-test-app", "supported":"true", "skip-profiling":"true", "skip-basic":"true"} fail-fast: false env: TEST_LIBRARY: ${{ inputs.library }} @@ -153,6 +193,7 @@ jobs: matrix: weblog: ${{ fromJson(needs.compute-matrix.outputs.matrix_supported_langs) }} lib_init_image: ${{ fromJson(needs.compute-matrix.outputs.init_image) }} + cluster_agent_version: ['7.56.2', '7.57.0', '7.59.0'] fail-fast: false env: TEST_LIBRARY: ${{ inputs.library }} @@ -161,6 +202,7 @@ jobs: SYSTEM_TESTS_REPORT_ENVIRONMENT: dev SYSTEM_TESTS_REPORT_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} LIBRARY_INJECTION_TEST_APP_IMAGE: ghcr.io/datadog/system-tests/${{ matrix.weblog }}:${{ inputs.build_lib_injection_app_images != true && 'latest' || github.sha }} + CLUSTER_AGENT_VERSION: ${{ matrix.cluster_agent_version }} steps: - name: Checkout uses: actions/checkout@v4 @@ -187,16 +229,30 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build weblog base images (PR) - if: inputs.build_lib_injection_app_images - run: lib-injection/build/build_lib_injection_weblog.sh -w ${{ matrix.weblog }} -l ${{ inputs.library }} --push-tag ${{ env.LIBRARY_INJECTION_TEST_APP_IMAGE }} - - name: Install runner uses: ./.github/actions/install_runner + - name: Build weblog base images (PR) + id: build + if: inputs.build_lib_injection_app_images + run: | + #Build multiplatform + lib-injection/build/build_lib_injection_weblog.sh -w ${{ matrix.weblog }} -l ${{ inputs.library }} --push-tag ${{ env.LIBRARY_INJECTION_TEST_APP_IMAGE }} --docker-platform linux/arm64,linux/amd64 + - name: Kubernetes lib-injection tests id: k8s-lib-injection-tests - run: ./run.sh K8S_LIBRARY_INJECTION_FULL + if: ${{ !contains(fromJson(needs.compute-matrix.outputs.matrix_skip_basic), matrix.weblog) }} + run: ./run.sh K8S_LIBRARY_INJECTION_BASIC + + - name: Kubernetes lib-injection profiling tests + id: k8s-lib-injection-tests-profiling + if: ${{ contains(fromJson(needs.compute-matrix.outputs.matrix_profiling_supported), matrix.weblog) }} + run: ./run.sh K8S_LIBRARY_INJECTION_PROFILING + + - name: Kubernetes lib-injection DJM tests + id: k8s-lib-injection-tests-djm + if: ${{ matrix.weblog == 'dd-djm-spark-test-app' }} + run: ./run.sh K8S_LIBRARY_INJECTION_DJM - name: Compress logs id: compress_logs @@ -207,5 +263,5 @@ jobs: if: always() && steps.compress_logs.outcome == 'success' uses: actions/upload-artifact@v4 with: - name: logs_k8s-lib-injection_${{ inputs.library}}_${{matrix.weblog}}_${{ endsWith(matrix.lib_init_image, 'latest_snapshot') == true && 'latest_snapshot' || 'latest'}} + name: logs_k8s-lib-injection_${{ inputs.library}}_${{matrix.weblog}}_${{matrix.cluster_agent_version}}_${{ endsWith(matrix.lib_init_image, 'latest_snapshot') == true && 'dev' || 'prod'}} path: artifact.tar.gz diff --git a/.github/workflows/run-open-telemetry.yml b/.github/workflows/run-open-telemetry.yml index 35fc56a1043..076e4ebfa32 100644 --- a/.github/workflows/run-open-telemetry.yml +++ b/.github/workflows/run-open-telemetry.yml @@ -17,11 +17,18 @@ on: default: "[]" required: false type: string + skip_empty_scenarios: + description: "Skip scenarios that contains only xfail or irrelevant tests" + default: false + required: false + type: boolean jobs: open-telemetry-manual: if: inputs.library == 'java' runs-on: ubuntu-latest + env: + SYSTEM_TESTS_SKIP_EMPTY_SCENARIO: ${{ inputs.skip_empty_scenarios }} steps: - name: Checkout uses: actions/checkout@v4 @@ -94,6 +101,7 @@ jobs: env: TEST_LIBRARY: ${{ inputs.library }}_otel WEBLOG_VARIANT: ${{ matrix.weblog }} + SYSTEM_TESTS_SKIP_EMPTY_SCENARIO: ${{ inputs.skip_empty_scenarios }} steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/run-parametric.yml b/.github/workflows/run-parametric.yml index 3b4f5cdab3c..5cc526789ed 100644 --- a/.github/workflows/run-parametric.yml +++ b/.github/workflows/run-parametric.yml @@ -16,6 +16,18 @@ on: default: 'custom' required: false type: string + _experimental_job_count: + description: "How many job should be spawned for the parametric test" + default: 1 + required: false + type: number + _experimental_job_matrix: + # github action syntax is not very powerfull, it require a job to compute this. + # => save on job, by asking the caller to compute this list + description: "Job matrix, JSON array of number from 1 to _experimental_job_count" + default: '[1]' + required: false + type: string env: REGISTRY: ghcr.io @@ -24,8 +36,11 @@ jobs: parametric: runs-on: group: "APM Larger Runners" + strategy: + fail-fast: false + matrix: + job_instance: ${{ fromJson( inputs._experimental_job_matrix ) }} env: - TEST_LIBRARY: ${{ inputs.library }} SYSTEM_TESTS_REPORT_ENVIRONMENT: ${{ inputs.ci_environment }} SYSTEM_TESTS_REPORT_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} steps: @@ -41,30 +56,8 @@ jobs: with: name: ${{ inputs.binaries_artifact }} path: binaries/ - - name: Run parametric tests (with timeout) - if: ${{ inputs.library == 'java' }} - run: | - set +e - RUN_ATTEMPTS=1 - while [ $RUN_ATTEMPTS -le 3 ]; do - echo "Running parametric test attempt $RUN_ATTEMPTS" - timeout 720s ./run.sh PARAMETRIC - status=$? - #timneout returns 124 if it times out - #if the return code is not 124, then we exit with the status - if [ $status -ne 124 ]; then - exit $status - break - fi - RUN_ATTEMPTS=$((RUN_ATTEMPTS+1)) - if [ $RUN_ATTEMPTS -eq 4 ]; then - #Max attempts reached, exit with 124 - exit 124 - fi - done - - name: Run parametric (without timeout) - if: ${{ inputs.library != 'java' }} - run: ./run.sh PARAMETRIC + - name: Run PARAMETRIC scenario + run: ./run.sh PARAMETRIC -L ${{ inputs.library }} --splits=${{ inputs._experimental_job_count }} --group=${{ matrix.job_instance }} - name: Compress logs id: compress_logs if: always() @@ -73,13 +66,10 @@ jobs: if: always() && steps.compress_logs.outcome == 'success' uses: actions/upload-artifact@v4 with: - name: logs_parametric_${{ inputs.library}}_parametric_${{ inputs.ci_environment }} + name: logs_parametric_${{ inputs.library}}_parametric_${{ inputs.ci_environment }}_${{ matrix.job_instance }} path: artifact.tar.gz # - name: Upload results CI Visibility # if: ${{ always() }} # run: ./utils/scripts/upload_results_CI_visibility.sh ${{ inputs.ci_environment }} system-tests ${{ github.run_id }}-${{ github.run_attempt }} # env: # DD_API_KEY: ${{ secrets.DD_CI_API_KEY }} - - name: Print fancy log report - if: ${{ always() }} - run: python utils/scripts/markdown_logs.py >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/system-tests.yml b/.github/workflows/system-tests.yml index cbd9844fda3..13978f3fd81 100644 --- a/.github/workflows/system-tests.yml +++ b/.github/workflows/system-tests.yml @@ -51,37 +51,26 @@ on: default: false required: false type: boolean + skip_empty_scenarios: + description: "Skip scenarios that contains only xfail or irrelevant tests" + default: false + required: false + type: boolean + _experimental_parametric_job_count: + description: "*EXPERIMENTAL* : How many jobs should be used to run PARAMETRIC scenario" + default: 1 + required: false + type: number jobs: compute_parameters: name: Get parameters - runs-on: ubuntu-latest - outputs: - endtoend_scenarios: ${{ steps.main.outputs.endtoend_scenarios }} - endtoend_weblogs: ${{ steps.main.outputs.endtoend_weblogs }} - graphql_scenarios: ${{ steps.main.outputs.graphql_scenarios }} - graphql_weblogs: ${{ steps.main.outputs.graphql_weblogs }} - libinjection_scenarios: ${{ steps.main.outputs.libinjection_scenarios }} - opentelemetry_scenarios: ${{ steps.main.outputs.opentelemetry_scenarios }} - opentelemetry_weblogs: ${{ steps.main.outputs.opentelemetry_weblogs }} - parametric_scenarios: ${{ steps.main.outputs.parametric_scenarios }} - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - repository: 'DataDog/system-tests' - - name: Install runner - uses: ./.github/actions/install_runner - - name: main - id: main - run: | - source venv/bin/activate - python utils/scripts/get_github_parameters.py >> $GITHUB_OUTPUT - env: - PYTHONPATH: "." - SCENARIOS: ${{ inputs.scenarios }} - SCENARIOS_GROUPS: ${{ inputs.scenarios_groups }} - LIBRARY: ${{ inputs.library }} + uses: ./.github/workflows/compute-workflow-parameters.yml + with: + library: ${{ inputs.library }} + scenarios: ${{ inputs.scenarios }} + scenarios_groups: ${{ inputs.scenarios_groups }} + _experimental_parametric_job_count: ${{ inputs._experimental_parametric_job_count }} parametric: needs: @@ -93,6 +82,8 @@ jobs: library: ${{ inputs.library }} binaries_artifact: ${{ inputs.binaries_artifact }} ci_environment: ${{ inputs.ci_environment }} + _experimental_job_count: ${{ inputs._experimental_parametric_job_count }} + _experimental_job_matrix: ${{ needs.compute_parameters.outputs._experimental_parametric_job_matrix }} graphql: needs: @@ -106,16 +97,21 @@ jobs: binaries_artifact: ${{ inputs.binaries_artifact }} ci_environment: ${{ inputs.ci_environment }} build_proxy_image: ${{ inputs.build_proxy_image }} + skip_empty_scenarios: ${{ inputs.skip_empty_scenarios }} lib-injection: needs: - compute_parameters - if: ${{ needs.compute_parameters.outputs.libinjection_scenarios != '[]' && inputs.binaries_artifact == '' }} + if: ${{ needs.compute_parameters.outputs.libinjection_scenarios != '[]' }} uses: ./.github/workflows/run-lib-injection.yml + permissions: + contents: read + packages: write secrets: inherit with: build_lib_injection_app_images: ${{ inputs.build_lib_injection_app_images }} library: ${{ inputs.library }} + version: ${{ inputs.binaries_artifact == '' && 'prod' || 'dev' }} end-to-end: needs: @@ -132,6 +128,7 @@ jobs: weblogs: ${{ needs.compute_parameters.outputs.endtoend_weblogs }} binaries_artifact: ${{ inputs.binaries_artifact }} ci_environment: ${{ inputs.ci_environment }} + skip_empty_scenarios: ${{ inputs.skip_empty_scenarios }} open-telemetry: needs: @@ -143,3 +140,15 @@ jobs: library: ${{ inputs.library }} weblogs: ${{ needs.compute_parameters.outputs.opentelemetry_weblogs }} build_proxy_image: ${{ inputs.build_proxy_image }} + skip_empty_scenarios: ${{ inputs.skip_empty_scenarios }} + + external-processing: + needs: + - compute_parameters + if: ${{ needs.compute_parameters.outputs.externalprocessing_scenarios != '[]' && inputs.library == 'golang' && inputs.binaries_artifact != ''}} + uses: ./.github/workflows/run-external-processing.yml + secrets: inherit + with: + build_proxy_image: ${{ inputs.build_proxy_image }} + ci_environment: ${{ inputs.ci_environment }} + binaries_artifact: ${{ inputs.binaries_artifact }} diff --git a/.github/workflows/update-agent-protobuf.yml b/.github/workflows/update-agent-protobuf.yml index 513c92191aa..7753ee35b13 100644 --- a/.github/workflows/update-agent-protobuf.yml +++ b/.github/workflows/update-agent-protobuf.yml @@ -8,16 +8,20 @@ on: jobs: main: runs-on: ubuntu-latest + permissions: + pull-requests: write steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v5 + with: + go-version: '1.21.13' - run: sudo apt-get update - run: sudo apt-get -y install protobuf-compiler - run: protoc --version && go version - name: Generate descriptor run: utils/scripts/update_protobuf.sh - name: Create Pull Request - uses: peter-evans/create-pull-request@v3 + uses: peter-evans/create-pull-request@v7 with: commit-message: Update protobuf descriptors branch: actions/update-protobuf-descriptors diff --git a/.gitignore b/.gitignore index 7da64465d12..5fe70512df1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .idea .env .envrc +.direnv __pycache__ binaries/* !binaries/README.md @@ -36,14 +37,23 @@ reportJunit.xml !lib-injection/build/docker/ruby/lib_injection_rails_app/bin !utils/build/docker/ruby/rails52/bin -/utils/build/docker/dotnet/.vs/app/* -/utils/build/docker/dotnet/app.csproj.user .ionide/ # Visual Studio .vs/ -.config/dotnet-tools.json +**/dotnet/**/*.user +**/dotnet/**/*.suo +*.DotSettings.user + +# .NET SDK +**/dotnet/**/bin/ +**/dotnet/**/obj/ +**/dotnet/**/packages/ +**/dotnet/**/out/ +**/.config/dotnet-tools.json + +# Created automatically by vscode's C# extension /system-tests.sln # Node.js @@ -52,3 +62,9 @@ node_modules/ # vim /*.vim *.swp + +utils/build/docker/*/parametric/Dockerfile + +# debugger +/tests/debugger/approvals/*received* +.aider* diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index acf9bcd5a6a..87d5026957a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,206 +1,454 @@ include: - remote: https://gitlab-templates.ddbuild.io/libdatadog/include/single-step-instrumentation-tests.yml - stages: - - ruby_tracer - - nodejs_tracer - - java_tracer - - python_tracer - - dotnet_tracer + - nodejs_ssi_pipelines + - java_ssi_pipelines + - python_ssi_pipelines + - php_ssi_pipelines + - dotnet_ssi_pipelines + - ruby_ssi_pipelines + - stats_results - parse_results - before_tests - -.base_job_onboarding_system_tests: - extends: .base_job_onboarding - after_script: - - SCENARIO_SUFIX=$(echo "$SCENARIO" | tr '[:upper:]' '[:lower:]') - - REPORTS_PATH="reports/" - - mkdir -p "$REPORTS_PATH" - - cp -R logs_"${SCENARIO_SUFIX}" $REPORTS_PATH/ - - cp logs_"${SCENARIO_SUFIX}"/feature_parity.json "$REPORTS_PATH"/"${SCENARIO_SUFIX}".json - - mv "$REPORTS_PATH"/logs_"${SCENARIO_SUFIX}" "$REPORTS_PATH"/logs_"${TEST_LIBRARY}"_"${ONBOARDING_FILTER_WEBLOG}"_"${SCENARIO_SUFIX}" - artifacts: - when: always - paths: - - reports/ + - k8s_lib_injection variables: # Do not modify this - must be the repository name for Kubernetes gitlab runners to run KUBERNETES_SERVICE_ACCOUNT_OVERWRITE: system-tests #helm-charts TEST: 1 -onboarding_nodejs: - extends: .base_job_onboarding_system_tests - stage: nodejs_tracer +.compute_aws_scenarios: + image: registry.ddbuild.io/ci/libdatadog-build/system-tests:48436362 + tags: ["arch:arm64"] + stage: nodejs_ssi_pipelines allow_failure: true - dependencies: [] - only: - - schedules variables: TEST_LIBRARY: "nodejs" - parallel: - matrix: - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-nodejs-profiling] - SCENARIO: [SIMPLE_HOST_AUTO_INJECTION_PROFILING] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-nodejs] - SCENARIO: [HOST_AUTO_INJECTION, HOST_AUTO_INJECTION_INSTALL_SCRIPT, HOST_AUTO_INJECTION_INSTALL_SCRIPT_PROFILING] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-shell-script] - SCENARIO: [HOST_AUTO_INJECTION_BLOCK_LIST] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-nodejs-container,test-app-nodejs-alpine-libgcc] - SCENARIO: [CONTAINER_AUTO_INJECTION, CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-nodejs,test-app-nodejs-container,test-app-nodejs-alpine-libgcc] - SCENARIO: [INSTALLER_AUTO_INJECTION] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-nodejs-alpine] - SCENARIO: [CONTAINER_NOT_SUPPORTED_AUTO_INJECTION] - + ONBOARDING_FILTER_WEBLOG: "test-app-nodejs" + SCENARIO: "HOST_AUTO_INJECTION_INSTALL_SCRIPT" + #Because sometimes I don't want to run all pipeline, I only run step1_xx with env filter param + ONBOARDING_FILTER_ENV: "$FILTER_ENV" + DD_INSTALLER_LIBRARY_VERSION: "$INSTALLER_LIBRARY_VERSION" + DD_INSTALLER_INJECTOR_VERSION: "$INSTALLER_INJECTOR_VERSION" + before_script: + - export DD_API_KEY_ONBOARDING=xyz + - export DD_APP_KEY_ONBOARDING=xyz script: - ./build.sh -i runner - - timeout 2700s ./run.sh $SCENARIO --vm-weblog ${ONBOARDING_FILTER_WEBLOG} --vm-env ${ONBOARDING_FILTER_ENV} --vm-library ${TEST_LIBRARY} --vm-provider aws + - ./run.sh $SCENARIO --vm-weblog ${ONBOARDING_FILTER_WEBLOG} --vm-env ${ONBOARDING_FILTER_ENV} --vm-library ${TEST_LIBRARY} --vm-provider aws --vm-default-vms All --vm-gitlab-pipeline system-tests + after_script: + - SCENARIO_SUFIX=$(echo "$SCENARIO" | tr '[:upper:]' '[:lower:]') + - mkdir -p reports/logs_"${SCENARIO_SUFIX}_${ONBOARDING_FILTER_WEBLOG}" + - cp -R logs_"${SCENARIO_SUFIX}"/gitlab_pipeline.yml reports/logs_"${SCENARIO_SUFIX}_${ONBOARDING_FILTER_WEBLOG}"/ + artifacts: + paths: + - reports/ -onboarding_java: - extends: .base_job_onboarding_system_tests - stage: java_tracer - allow_failure: true +.x_compute_docker_scenarios: + image: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/test-infra-definitions/runner:a58cc31c + tags: ["arch:amd64"] + stage: nodejs_ssi_pipelines + variables: + TEST_LIBRARY: "nodejs" + #Because sometimes I don't want to run all pipeline, I only run step1_xx with env filter param + ONBOARDING_FILTER_ENV: "$FILTER_ENV" + script: + - python utils/docker_ssi/docker_ssi_matrix_builder.py --language $TEST_LIBRARY --format yaml --output-file gitlab_pipeline.yml + needs: + - job: step1_generate_nodejs_ssi_pipeline + artifacts: true + after_script: + - SCENARIO_SUFIX="docker_ssi" + - mkdir -p reports/logs_"${SCENARIO_SUFIX}" + - cp gitlab_pipeline.yml reports/logs_"${SCENARIO_SUFIX}"/ + artifacts: + paths: + - reports/ + +.merge_aws_ssi_pipeline: + image: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/test-infra-definitions/runner:a58cc31c + stage: nodejs_ssi_pipelines + tags: ["arch:amd64"] + script: + - | + for folder in reports/logs*/ ; do + echo "Checking folder:: ${folder}" + for filename in ./${folder}gitlab_pipeline.yml; do + if [ -e ${filename} ] + then + echo "Processing pipeline: ${filename}" + python utils/scripts/merge_gitlab_aws_pipelines.py --input ${filename} --output aws_gitlab_pipeline.yml + fi + done + done + needs: ["onboarding_nodejs"] + dependencies: + - onboarding_nodejs + artifacts: + paths: + - aws_gitlab_pipeline.yml + +.exec_aws_ssi_pipeline: + stage: nodejs_ssi_pipelines + needs: ["merge_aws_ssi_pipeline"] + rules: + - if: $CI_PIPELINE_SOURCE == "schedule" + when: always + - when: manual + allow_failure: true + variables: + PARENT_PIPELINE_SOURCE: $CI_PIPELINE_SOURCE + trigger: + include: + - artifact: aws_gitlab_pipeline.yml + job: merge_aws_ssi_pipeline + strategy: depend + +.step1_generate_aws_ssi_pipeline: + "image": "registry.ddbuild.io/docker:20.10.13-gbi-focal" + "tags": ["arch:amd64"] + stage: nodejs_ssi_pipelines + script: + - echo ">>>>>>>>>>>>>>> Generating lang pipeline >>>>>>>>>>>>>>>" + - echo "FILTER_ENV=${ONBOARDING_FILTER_ENV:-prod}" >> run.env + - echo "INSTALLER_LIBRARY_VERSION=${DD_INSTALLER_LIBRARY_VERSION:- }" >> run.env + - echo "INSTALLER_INJECTOR_VERSION=${DD_INSTALLER_INJECTOR_VERSION:- }" >> run.env + rules: + - if: $CI_PIPELINE_SOURCE == "schedule" + when: always + - when: manual + allow_failure: true + artifacts: + reports: + dotenv: run.env + +# ----------- Nodejs SSI ---------------- +step1_generate_nodejs_ssi_pipeline: + extends: .step1_generate_aws_ssi_pipeline + needs: [] + +x_compute_nodejs_scenarios: + extends: .compute_aws_scenarios + variables: + TEST_LIBRARY: "nodejs" + parallel: + matrix: + - ONBOARDING_FILTER_WEBLOG: [test-app-nodejs] + SCENARIO: + - HOST_AUTO_INJECTION_INSTALL_SCRIPT + - HOST_AUTO_INJECTION_INSTALL_SCRIPT_PROFILING + - ONBOARDING_FILTER_WEBLOG: [test-app-nodejs-multicontainer] + SCENARIO: + - CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT + - CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT_PROFILING + - ONBOARDING_FILTER_WEBLOG: [test-app-nodejs,test-app-nodejs-container] + SCENARIO: [INSTALLER_AUTO_INJECTION,SIMPLE_AUTO_INJECTION_PROFILING] + - ONBOARDING_FILTER_WEBLOG: [test-app-nodejs-08, test-app-nodejs-16, test-app-nodejs-unsupported-defaults] + SCENARIO: [INSTALLER_NOT_SUPPORTED_AUTO_INJECTION] + - ONBOARDING_FILTER_WEBLOG: [test-app-nodejs] + SCENARIO: [CHAOS_INSTALLER_AUTO_INJECTION] + - ONBOARDING_FILTER_WEBLOG: [test-app-nodejs-multicontainer,test-app-nodejs-esm] + SCENARIO: [SIMPLE_INSTALLER_AUTO_INJECTION] + needs: + - job: step1_generate_nodejs_ssi_pipeline + artifacts: true + +x_compute_nodejs_docker_scenarios: + extends: .x_compute_docker_scenarios + stage: nodejs_ssi_pipelines + variables: + TEST_LIBRARY: "nodejs" + needs: + - job: step1_generate_nodejs_ssi_pipeline + artifacts: true + +x_merge_nodejs_ssi_pipeline: + extends: .merge_aws_ssi_pipeline + needs: ["x_compute_nodejs_scenarios", "x_compute_nodejs_docker_scenarios"] + dependencies: + - x_compute_nodejs_scenarios + - x_compute_nodejs_docker_scenarios + +step2_exec_nodejs_ssi_pipeline: + extends: .exec_aws_ssi_pipeline + needs: ["x_merge_nodejs_ssi_pipeline"] + trigger: + include: + - artifact: aws_gitlab_pipeline.yml + job: x_merge_nodejs_ssi_pipeline + strategy: depend + + +# ----------- Java SSI ---------------- +step1_generate_java_ssi_pipeline: + stage: java_ssi_pipelines dependencies: [] - only: - - schedules + extends: .step1_generate_aws_ssi_pipeline + +x_compute_java_scenarios: + stage: java_ssi_pipelines + extends: .compute_aws_scenarios variables: TEST_LIBRARY: "java" parallel: - matrix: - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-java] - SCENARIO: [HOST_AUTO_INJECTION, HOST_AUTO_INJECTION_INSTALL_SCRIPT] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-shell-script] - SCENARIO: [HOST_AUTO_INJECTION_BLOCK_LIST] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-java-container,test-app-java-container-jdk15,test-app-java-alpine-libgcc,test-app-java-buildpack] - SCENARIO: [CONTAINER_AUTO_INJECTION, CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-java,test-app-java-container,test-app-java-alpine-libgcc,test-app-java-buildpack] + matrix: + - ONBOARDING_FILTER_WEBLOG: [test-app-java] + SCENARIO: + - HOST_AUTO_INJECTION_INSTALL_SCRIPT + - HOST_AUTO_INJECTION_INSTALL_SCRIPT_PROFILING + - ONBOARDING_FILTER_WEBLOG: [test-app-java-multicontainer,test-app-java-multialpine] + SCENARIO: + - CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT + - CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT_PROFILING + - ONBOARDING_FILTER_WEBLOG: [test-app-java,test-app-java-container,test-app-java-alpine,test-app-java-buildpack] SCENARIO: [INSTALLER_AUTO_INJECTION] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-java-alpine,test-app-java-alpine-jdk15,test-app-java-alpine-jdk21] - SCENARIO: [CONTAINER_NOT_SUPPORTED_AUTO_INJECTION] + - ONBOARDING_FILTER_WEBLOG: [test-app-java,test-app-java-multicontainer,test-app-java-multialpine] + SCENARIO: [SIMPLE_AUTO_INJECTION_PROFILING] + - ONBOARDING_FILTER_WEBLOG: [test-app-java] + SCENARIO: [CHAOS_INSTALLER_AUTO_INJECTION] + - ONBOARDING_FILTER_WEBLOG: [test-app-java-multicontainer,test-app-java-multialpine] + SCENARIO: [SIMPLE_INSTALLER_AUTO_INJECTION] + needs: + - job: step1_generate_java_ssi_pipeline + artifacts: true - script: - - ./build.sh -i runner - - timeout 2700s ./run.sh $SCENARIO --vm-weblog ${ONBOARDING_FILTER_WEBLOG} --vm-env ${ONBOARDING_FILTER_ENV} --vm-library ${TEST_LIBRARY} --vm-provider aws +x_compute_java_docker_scenarios: + extends: .x_compute_docker_scenarios + stage: java_ssi_pipelines + variables: + TEST_LIBRARY: "java" + needs: + - job: step1_generate_java_ssi_pipeline + artifacts: true -onboarding_python: - extends: .base_job_onboarding_system_tests - stage: python_tracer - allow_failure: true +x_merge_java_ssi_pipeline: + stage: java_ssi_pipelines + extends: .merge_aws_ssi_pipeline + needs: ["x_compute_java_scenarios", "x_compute_java_docker_scenarios"] + dependencies: + - x_compute_java_scenarios + - x_compute_java_docker_scenarios + +step2_exec_java_ssi_pipeline: + stage: java_ssi_pipelines + extends: .exec_aws_ssi_pipeline + needs: ["x_merge_java_ssi_pipeline"] + trigger: + include: + - artifact: aws_gitlab_pipeline.yml + job: x_merge_java_ssi_pipeline + strategy: depend + +# ----------- Python SSI ---------------- +step1_generate_python_ssi_pipeline: + stage: python_ssi_pipelines dependencies: [] - only: - - schedules + extends: .step1_generate_aws_ssi_pipeline + +x_compute_python_scenarios: + stage: python_ssi_pipelines + extends: .compute_aws_scenarios variables: TEST_LIBRARY: "python" parallel: matrix: - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-python] - SCENARIO: [HOST_AUTO_INJECTION, HOST_AUTO_INJECTION_INSTALL_SCRIPT] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-shell-script] - SCENARIO: [HOST_AUTO_INJECTION_BLOCK_LIST] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-python-container,test-app-python-alpine-libgcc] - SCENARIO: [CONTAINER_AUTO_INJECTION, CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-python,test-app-python-container,test-app-python-alpine-libgcc] + - ONBOARDING_FILTER_WEBLOG: [test-app-python] + SCENARIO: [HOST_AUTO_INJECTION_INSTALL_SCRIPT] + - ONBOARDING_FILTER_WEBLOG: [test-app-python-container,test-app-python-alpine] + SCENARIO: [ CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT] + - ONBOARDING_FILTER_WEBLOG: [ + test-app-python, + test-app-python-container, + test-app-python-alpine + ] SCENARIO: [INSTALLER_AUTO_INJECTION] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-python-alpine] - SCENARIO: [CONTAINER_NOT_SUPPORTED_AUTO_INJECTION] - script: - - ./build.sh -i runner - - timeout 2700s ./run.sh $SCENARIO --vm-weblog ${ONBOARDING_FILTER_WEBLOG} --vm-env ${ONBOARDING_FILTER_ENV} --vm-library ${TEST_LIBRARY} --vm-provider aws + - ONBOARDING_FILTER_WEBLOG: [test-app-python] + SCENARIO: [CHAOS_INSTALLER_AUTO_INJECTION] + - ONBOARDING_FILTER_WEBLOG: [test-app-python-multicontainer,test-app-python-multialpine] + SCENARIO: [SIMPLE_INSTALLER_AUTO_INJECTION] + - ONBOARDING_FILTER_WEBLOG: [test-app-python-unsupported-defaults,test-app-python-27] + SCENARIO: [INSTALLER_NOT_SUPPORTED_AUTO_INJECTION] + needs: + - job: step1_generate_python_ssi_pipeline + artifacts: true -onboarding_dotnet: - extends: .base_job_onboarding_system_tests - stage: dotnet_tracer - allow_failure: true +x_compute_python_docker_scenarios: + extends: .x_compute_docker_scenarios + stage: python_ssi_pipelines + variables: + TEST_LIBRARY: "python" + needs: + - job: step1_generate_python_ssi_pipeline + artifacts: true + +x_merge_python_ssi_pipeline: + stage: python_ssi_pipelines + extends: .merge_aws_ssi_pipeline + needs: ["x_compute_python_scenarios", "x_compute_python_docker_scenarios"] + dependencies: + - x_compute_python_scenarios + - x_compute_python_docker_scenarios + +step2_exec_python_ssi_pipeline: + stage: python_ssi_pipelines + extends: .exec_aws_ssi_pipeline + needs: ["x_merge_python_ssi_pipeline"] + trigger: + include: + - artifact: aws_gitlab_pipeline.yml + job: x_merge_python_ssi_pipeline + strategy: depend + +# ----------- PHP SSI ---------------- +step1_generate_php_ssi_pipeline: + stage: php_ssi_pipelines dependencies: [] - only: - - schedules + extends: .step1_generate_aws_ssi_pipeline + +x_compute_php_scenarios: + stage: php_ssi_pipelines + extends: .compute_aws_scenarios variables: - TEST_LIBRARY: "dotnet" + TEST_LIBRARY: "php" parallel: matrix: - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-dotnet] - SCENARIO: [HOST_AUTO_INJECTION, HOST_AUTO_INJECTION_INSTALL_SCRIPT] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-shell-script] - SCENARIO: [HOST_AUTO_INJECTION_BLOCK_LIST] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-dotnet,test-app-dotnet-container] + - ONBOARDING_FILTER_WEBLOG: [test-app-php] + SCENARIO: [HOST_AUTO_INJECTION_INSTALL_SCRIPT] + - ONBOARDING_FILTER_WEBLOG: [test-app-php-container-83,test-app-php-alpine] + SCENARIO: [CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT] + - ONBOARDING_FILTER_WEBLOG: [test-app-php, test-app-php-container-83, test-app-php-alpine] SCENARIO: [INSTALLER_AUTO_INJECTION] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-dotnet-container] - SCENARIO: [CONTAINER_AUTO_INJECTION, CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT] - script: - - ./build.sh -i runner - - timeout 2700s ./run.sh $SCENARIO --vm-weblog ${ONBOARDING_FILTER_WEBLOG} --vm-env ${ONBOARDING_FILTER_ENV} --vm-library ${TEST_LIBRARY} --vm-provider aws + - ONBOARDING_FILTER_WEBLOG: [test-app-php] + SCENARIO: [CHAOS_INSTALLER_AUTO_INJECTION] + - ONBOARDING_FILTER_WEBLOG: [test-app-php-container-56] + SCENARIO: [INSTALLER_NOT_SUPPORTED_AUTO_INJECTION] + - ONBOARDING_FILTER_WEBLOG: [test-app-php-multicontainer, test-app-php-multialpine] + SCENARIO: [SIMPLE_INSTALLER_AUTO_INJECTION] + needs: + - job: step1_generate_php_ssi_pipeline + artifacts: true -onboarding_ruby: - extends: .base_job_onboarding_system_tests - stage: ruby_tracer - allow_failure: true +x_compute_php_docker_scenarios: + extends: .x_compute_docker_scenarios + stage: php_ssi_pipelines + variables: + TEST_LIBRARY: "php" + needs: + - job: step1_generate_php_ssi_pipeline + artifacts: true + +x_merge_php_ssi_pipeline: + stage: php_ssi_pipelines + extends: .merge_aws_ssi_pipeline + needs: ["x_compute_php_scenarios", "x_compute_php_docker_scenarios"] + dependencies: + - x_compute_php_scenarios + - x_compute_php_docker_scenarios + +step2_exec_php_ssi_pipeline: + stage: php_ssi_pipelines + extends: .exec_aws_ssi_pipeline + needs: ["x_merge_php_ssi_pipeline"] + trigger: + include: + - artifact: aws_gitlab_pipeline.yml + job: x_merge_php_ssi_pipeline + strategy: depend + +# ----------- Dotnet SSI ---------------- +step1_generate_dotnet_ssi_pipeline: + stage: dotnet_ssi_pipelines dependencies: [] - only: - - schedules + extends: .step1_generate_aws_ssi_pipeline + +x_compute_dotnet_scenarios: + stage: dotnet_ssi_pipelines + extends: .compute_aws_scenarios + variables: + TEST_LIBRARY: "dotnet" + parallel: + matrix: + - ONBOARDING_FILTER_WEBLOG: [test-app-dotnet] + SCENARIO: + - HOST_AUTO_INJECTION_INSTALL_SCRIPT + - HOST_AUTO_INJECTION_INSTALL_SCRIPT_PROFILING + - ONBOARDING_FILTER_WEBLOG: [test-app-dotnet-container] + SCENARIO: + - CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT + - CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT_PROFILING + - ONBOARDING_FILTER_WEBLOG: [test-app-dotnet,test-app-dotnet-container] + SCENARIO: [INSTALLER_AUTO_INJECTION, SIMPLE_AUTO_INJECTION_PROFILING] + - ONBOARDING_FILTER_WEBLOG: [test-app-dotnet] + SCENARIO: [CHAOS_INSTALLER_AUTO_INJECTION] + - ONBOARDING_FILTER_WEBLOG: [test-app-dotnet-multicontainer,test-app-dotnet-multialpine] + SCENARIO: [SIMPLE_INSTALLER_AUTO_INJECTION] + - ONBOARDING_FILTER_WEBLOG: [test-app-dotnet-unsupported] + SCENARIO: [INSTALLER_NOT_SUPPORTED_AUTO_INJECTION] + needs: + - job: step1_generate_dotnet_ssi_pipeline + artifacts: true + +x_merge_dotnet_ssi_pipeline: + stage: dotnet_ssi_pipelines + extends: .merge_aws_ssi_pipeline + needs: ["x_compute_dotnet_scenarios"] + dependencies: + - x_compute_dotnet_scenarios + +step2_exec_dotnet_ssi_pipeline: + stage: dotnet_ssi_pipelines + extends: .exec_aws_ssi_pipeline + needs: ["x_merge_dotnet_ssi_pipeline"] + trigger: + include: + - artifact: aws_gitlab_pipeline.yml + job: x_merge_dotnet_ssi_pipeline + strategy: depend + +# ----------- Ruby SSI ---------------- +step1_generate_ruby_ssi_pipeline: + stage: ruby_ssi_pipelines + dependencies: [] + extends: .step1_generate_aws_ssi_pipeline + +x_compute_ruby_scenarios: + stage: ruby_ssi_pipelines + extends: .compute_aws_scenarios variables: TEST_LIBRARY: "ruby" parallel: matrix: - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-ruby] - SCENARIO: [HOST_AUTO_INJECTION, HOST_AUTO_INJECTION_INSTALL_SCRIPT] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-shell-script] - SCENARIO: [HOST_AUTO_INJECTION_BLOCK_LIST] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-ruby-container] - SCENARIO: [CONTAINER_AUTO_INJECTION, CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT] - - ONBOARDING_FILTER_ENV: [dev, prod] - ONBOARDING_FILTER_WEBLOG: [test-app-ruby,test-app-ruby-container] + - ONBOARDING_FILTER_WEBLOG: [test-app-ruby] + SCENARIO: [HOST_AUTO_INJECTION_INSTALL_SCRIPT] + - ONBOARDING_FILTER_WEBLOG: [test-app-ruby-container] + SCENARIO: [ CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT] + - ONBOARDING_FILTER_WEBLOG: [test-app-ruby,test-app-ruby-container] SCENARIO: [INSTALLER_AUTO_INJECTION] - script: - - ./build.sh -i runner - - timeout 2700s ./run.sh $SCENARIO --vm-weblog ${ONBOARDING_FILTER_WEBLOG} --vm-env ${ONBOARDING_FILTER_ENV} --vm-library ${TEST_LIBRARY} --vm-provider aws + - ONBOARDING_FILTER_WEBLOG: [test-app-ruby] + SCENARIO: [CHAOS_INSTALLER_AUTO_INJECTION] + - ONBOARDING_FILTER_WEBLOG: [test-app-ruby-multicontainer] + SCENARIO: [SIMPLE_INSTALLER_AUTO_INJECTION] + needs: + - job: step1_generate_ruby_ssi_pipeline + artifacts: true + +x_merge_ruby_ssi_pipeline: + stage: ruby_ssi_pipelines + extends: .merge_aws_ssi_pipeline + needs: ["x_compute_ruby_scenarios"] + dependencies: + - x_compute_ruby_scenarios + +step2_exec_ruby_ssi_pipeline: + stage: ruby_ssi_pipelines + extends: .exec_aws_ssi_pipeline + needs: ["x_merge_ruby_ssi_pipeline"] + trigger: + include: + - artifact: aws_gitlab_pipeline.yml + job: x_merge_ruby_ssi_pipeline + strategy: depend -onboarding_parse_results: - image: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/test-infra-definitions/runner:a58cc31c - tags: ["arch:amd64"] - stage: parse_results - only: - - schedules - before_script: - #We need authenticate on git repository - - export FP_IMPORT_URL=$(aws ssm get-parameter --region us-east-1 --name ci.system-tests.fp-import-url --with-decryption --query "Parameter.Value" --out text) - - export FP_API_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.system-tests.fp-api-key --with-decryption --query "Parameter.Value" --out text) - script: - - | - for folder in reports/logs*/ ; do - if [ -e ./${folder}feature_parity.json ] - then - curl -X POST ${FP_IMPORT_URL} \ - --fail \ - --header "Content-Type: application/json" \ - --header "FP_API_KEY: ${FP_API_KEY}" \ - --data "@./${folder}feature_parity.json" \ - --include - fi - done check_merge_labels: #Build docker images if it's needed. Check if the PR has the labels associated with the image build. @@ -214,6 +462,7 @@ check_merge_labels: - export DOCKER_LOGIN=$(aws ssm get-parameter --region us-east-1 --name ci.system-tests.docker-login-write --with-decryption --query "Parameter.Value" --out text) - export DOCKER_LOGIN_PASS=$(aws ssm get-parameter --region us-east-1 --name ci.system-tests.docker-login-pass-write --with-decryption --query "Parameter.Value" --out text) script: + - echo $GH_TOKEN | docker login ghcr.io -u publisher --password-stdin - ./utils/scripts/get_pr_merged_labels.sh rules: - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main" @@ -229,7 +478,143 @@ generate_system_tests_images: - export DOCKER_LOGIN=$(aws ssm get-parameter --region us-east-1 --name ci.system-tests.docker-login-write --with-decryption --query "Parameter.Value" --out text) - export DOCKER_LOGIN_PASS=$(aws ssm get-parameter --region us-east-1 --name ci.system-tests.docker-login-pass-write --with-decryption --query "Parameter.Value" --out text) script: + - echo $GH_TOKEN | docker login ghcr.io -u publisher --password-stdin - ./utils/build/build_tracer_buddies.sh --push - ./utils/build/build_python_base_images.sh --push - ./lib-injection/build/build_lib_injection_images.sh when: manual + +.k8s_lib_injection_base: + image: registry.ddbuild.io/ci/libdatadog-build/system-tests:48436362 + tags: [ "runner:docker" ] + stage: k8s_lib_injection + rules: + #- if: $CI_PIPELINE_SOURCE == "schedule" + # when: always + - when: manual + variables: + TEST_LIBRARY: "xyz" + K8S_WEBLOG: "xyz" + K8S_WEBLOG_IMG: "xyz" + K8S_SCENARIO: "xyz" + K8S_LIB_INIT_IMG: "xyz" + K8S_CLUSTER_VERSION: "xyz" + script: + - ./build.sh -i runner # rebuild runner in case there were changes + - source venv/bin/activate + - python --version + - pip freeze + - ./run.sh ${K8S_SCENARIO} --k8s-library ${TEST_LIBRARY} --k8s-weblog ${K8S_WEBLOG} --k8s-weblog-img ${K8S_WEBLOG_IMG} --k8s-lib-init-img ${K8S_LIB_INIT_IMG} --k8s-cluster-version ${K8S_CLUSTER_VERSION} + after_script: + - mkdir -p reports + - cp -R logs_*/ reports/ + - kind delete clusters --all || true + artifacts: + when: always + paths: + - reports/ + +k8s_java: + extends: .k8s_lib_injection_base + variables: + TEST_LIBRARY: "java" + parallel: + matrix: + - K8S_WEBLOG: [dd-djm-spark-test-app ] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/dd-djm-spark-test-app:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION_SPARK_DJM] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-java-init:latest", "ghcr.io/datadog/dd-trace-java/dd-lib-java-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.57.0', '7.59.0'] + - K8S_WEBLOG: [dd-lib-java-init-test-app] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/dd-lib-java-init-test-app:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION, K8S_LIB_INJECTION_UDS, K8S_LIB_INJECTION_NO_AC, K8S_LIB_INJECTION_NO_AC_UDS, K8S_LIB_INJECTION_PROFILING_DISABLED, K8S_LIB_INJECTION_PROFILING_ENABLED, K8S_LIB_INJECTION_PROFILING_OVERRIDE] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-java-init:latest", "ghcr.io/datadog/dd-trace-java/dd-lib-java-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.56.2', '7.57.0', '7.59.0'] + +k8s_dotnet: + extends: .k8s_lib_injection_base + variables: + TEST_LIBRARY: "dotnet" + parallel: + matrix: + - K8S_WEBLOG: [dd-lib-dotnet-init-test-app] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/dd-lib-dotnet-init-test-app:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION, K8S_LIB_INJECTION_UDS, K8S_LIB_INJECTION_NO_AC, K8S_LIB_INJECTION_NO_AC_UDS, K8S_LIB_INJECTION_PROFILING_DISABLED, K8S_LIB_INJECTION_PROFILING_ENABLED, K8S_LIB_INJECTION_PROFILING_OVERRIDE] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-dotnet-init:latest", "ghcr.io/datadog/dd-trace-dotnet/dd-lib-dotnet-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.56.2', '7.57.0', '7.59.0'] + +k8s_nodejs: + extends: .k8s_lib_injection_base + variables: + TEST_LIBRARY: "nodejs" + parallel: + matrix: + - K8S_WEBLOG: [sample-app] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/sample-app:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION, K8S_LIB_INJECTION_UDS, K8S_LIB_INJECTION_NO_AC, K8S_LIB_INJECTION_NO_AC_UDS, K8S_LIB_INJECTION_PROFILING_DISABLED, K8S_LIB_INJECTION_PROFILING_ENABLED, K8S_LIB_INJECTION_PROFILING_OVERRIDE] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-js-init:latest", "ghcr.io/datadog/dd-trace-js/dd-lib-js-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.56.2', '7.57.0', '7.59.0'] + +k8s_python: + extends: .k8s_lib_injection_base + variables: + TEST_LIBRARY: "python" + parallel: + matrix: + - K8S_WEBLOG: [dd-lib-python-init-test-django] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/dd-lib-python-init-test-django:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION, K8S_LIB_INJECTION_UDS, K8S_LIB_INJECTION_NO_AC, K8S_LIB_INJECTION_NO_AC_UDS, K8S_LIB_INJECTION_PROFILING_DISABLED, K8S_LIB_INJECTION_PROFILING_ENABLED, K8S_LIB_INJECTION_PROFILING_OVERRIDE] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-python-init:latest", "ghcr.io/datadog/dd-trace-py/dd-lib-python-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.56.2', '7.57.0', '7.59.0'] + - K8S_WEBLOG: [dd-lib-python-init-test-django-gunicorn] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/dd-lib-python-init-test-django-gunicorn:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION, K8S_LIB_INJECTION_PROFILING_ENABLED] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-python-init:latest", "ghcr.io/datadog/dd-trace-py/dd-lib-python-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.56.2', '7.57.0', '7.59.0'] + - K8S_WEBLOG: [dd-lib-python-init-test-django-gunicorn-alpine] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/dd-lib-python-init-test-django-gunicorn-alpine:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION, K8S_LIB_INJECTION_PROFILING_ENABLED] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-python-init:latest", "ghcr.io/datadog/dd-trace-py/dd-lib-python-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.56.2', '7.57.0', '7.59.0'] + - K8S_WEBLOG: [dd-lib-python-init-test-django-unsupported-package-force] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/dd-lib-python-init-test-django-unsupported-package-force:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION, K8S_LIB_INJECTION_PROFILING_ENABLED] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-python-init:latest", "ghcr.io/datadog/dd-trace-py/dd-lib-python-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.56.2', '7.57.0', '7.59.0'] + - K8S_WEBLOG: [dd-lib-python-init-test-django-uvicorn] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/dd-lib-python-init-test-django-uvicorn:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION, K8S_LIB_INJECTION_PROFILING_ENABLED] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-python-init:latest", "ghcr.io/datadog/dd-trace-py/dd-lib-python-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.56.2', '7.57.0', '7.59.0'] + - K8S_WEBLOG: [dd-lib-python-init-test-protobuf-old] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/dd-lib-python-init-test-protobuf-old:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION, K8S_LIB_INJECTION_PROFILING_ENABLED] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-python-init:latest", "ghcr.io/datadog/dd-trace-py/dd-lib-python-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.56.2', '7.57.0', '7.59.0'] + - K8S_WEBLOG: [dd-lib-python-init-test-django-preinstalled] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/dd-lib-python-init-test-django-preinstalled:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION, K8S_LIB_INJECTION_UDS, K8S_LIB_INJECTION_NO_AC, K8S_LIB_INJECTION_NO_AC_UDS] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-python-init:latest", "ghcr.io/datadog/dd-trace-py/dd-lib-python-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.56.2', '7.57.0', '7.59.0'] + +k8s_ruby: + extends: .k8s_lib_injection_base + variables: + TEST_LIBRARY: "ruby" + parallel: + matrix: + - K8S_WEBLOG: [dd-lib-ruby-init-test-rails] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/dd-lib-ruby-init-test-rails:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION, K8S_LIB_INJECTION_UDS, K8S_LIB_INJECTION_NO_AC, K8S_LIB_INJECTION_NO_AC_UDS, K8S_LIB_INJECTION_PROFILING_DISABLED, K8S_LIB_INJECTION_PROFILING_ENABLED, K8S_LIB_INJECTION_PROFILING_OVERRIDE] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-ruby-init:latest", "ghcr.io/datadog/dd-trace-rb/dd-lib-ruby-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.56.2', '7.57.0', '7.59.0'] + - K8S_WEBLOG: [dd-lib-ruby-init-test-rails-explicit] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/dd-lib-ruby-init-test-rails-explicit:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION, K8S_LIB_INJECTION_UDS, K8S_LIB_INJECTION_NO_AC, K8S_LIB_INJECTION_NO_AC_UDS, K8S_LIB_INJECTION_PROFILING_DISABLED, K8S_LIB_INJECTION_PROFILING_ENABLED, K8S_LIB_INJECTION_PROFILING_OVERRIDE] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-ruby-init:latest", "ghcr.io/datadog/dd-trace-rb/dd-lib-ruby-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.56.2', '7.57.0', '7.59.0'] + - K8S_WEBLOG: [dd-lib-ruby-init-test-rails-gemsrb] + K8S_WEBLOG_IMG: [ghcr.io/datadog/system-tests/dd-lib-ruby-init-test-rails-gemsrb:latest] + K8S_SCENARIO: [K8S_LIB_INJECTION, K8S_LIB_INJECTION_UDS, K8S_LIB_INJECTION_NO_AC, K8S_LIB_INJECTION_NO_AC_UDS, K8S_LIB_INJECTION_PROFILING_DISABLED, K8S_LIB_INJECTION_PROFILING_ENABLED, K8S_LIB_INJECTION_PROFILING_OVERRIDE] + K8S_LIB_INIT_IMG: ["gcr.io/datadoghq/dd-lib-ruby-init:latest", "ghcr.io/datadog/dd-trace-rb/dd-lib-ruby-init:latest_snapshot"] + K8S_CLUSTER_VERSION: ['7.56.2', '7.57.0', '7.59.0'] \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index b294a1f24a7..31d487b7746 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -34,6 +34,16 @@ "justMyCode": true, "python": "${workspaceFolder}/venv/bin/python" }, + { + "name": "Run INTEGRATIONS_AWS scenario", + "type": "python", + "request": "launch", + "module": "pytest", + "args": ["-S", "INTEGRATIONS_AWS", "-p", "no:warnings"], + "console": "integratedTerminal", + "justMyCode": true, + "python": "${workspaceFolder}/venv/bin/python" + }, { "name": "Replay CROSSED_TRACING_LIBRARIES scenario", "type": "python", @@ -54,6 +64,26 @@ "justMyCode": true, "python": "${workspaceFolder}/venv/bin/python" }, + { + "name": "Run TRACING_CONFIG_NONDEFAULT scenario", + "type": "python", + "request": "launch", + "module": "pytest", + "args": ["-S", "TRACING_CONFIG_NONDEFAULT", "-p", "no:warnings"], + "console": "integratedTerminal", + "justMyCode": true, + "python": "${workspaceFolder}/venv/bin/python" + }, + { + "name": "Run TRACING_CONFIG_NONDEFAULT_2 scenario", + "type": "python", + "request": "launch", + "module": "pytest", + "args": ["-S", "TRACING_CONFIG_NONDEFAULT_2", "-p", "no:warnings"], + "console": "integratedTerminal", + "justMyCode": true, + "python": "${workspaceFolder}/venv/bin/python" + }, { "name": "Run PROFILING scenario", "type": "python", @@ -114,6 +144,16 @@ "justMyCode": true, "python": "${workspaceFolder}/venv/bin/python" }, + { + "name": "Run IPV6 scenario", + "type": "python", + "request": "launch", + "module": "pytest", + "args": ["-S", "IPV6", "-p", "no:warnings"], + "console": "integratedTerminal", + "justMyCode": true, + "python": "${workspaceFolder}/venv/bin/python" + }, { "name": "Python: Current File", "type": "python", diff --git a/.vscode/settings.json b/.vscode/settings.json index 5437d07b771..750c534a07d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,5 +6,7 @@ "tests", "--replay" ], - "python.testing.pytestEnabled": true + "python.testing.pytestEnabled": true, + "ruff.enable": true, + "pylint.ignorePatterns": ["*"] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 881a5861686..07616dd0498 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,63 @@ All notable changes to this project will be documented in this file. +### 2024-11 (207 PR merged) + +* 2024-11-22 [Docker SSI: report data to FPD](https://github.com/DataDog/system-tests/pull/3525) by @robertomonteromiguel +* 2024-11-21 [adding mypy checks](https://github.com/DataDog/system-tests/pull/3488) by @rachelyangdog +* 2024-11-18 [[ruby] Add Rails 7.2 and Rails 8.0 weblogs](https://github.com/DataDog/system-tests/pull/3471) by @vpellan +* 2024-11-13 [Use a unique way to define scenario groups #3400](https://github.com/DataDog/system-tests/pull/3451) by @cbeauchesne +* 2024-11-18 [Test for zombie processes in crashtracking](https://github.com/DataDog/system-tests/pull/3364) by @kevingosse +* 2024-11-04 [Fix parametric instability at container start](https://github.com/DataDog/system-tests/pull/3359) by @cbeauchesne +* 2024-11-06 [parametric: Adds a feature to track the parity for parametric endpoints](https://github.com/DataDog/system-tests/pull/3345) by @mabdinur +* 2024-11-04 [[golang] Migrate Parametric app from grpc to http](https://github.com/DataDog/system-tests/pull/3332) by @mtoffl01 + + +### 2024-10 (176 PR merged) + +* Lot of work done on SSI/onboarding by @robertomonteromiguel and @emmettbutler +* 2024-10-24 [[Ruby] Convert parametric implementation from grpc to http](https://github.com/DataDog/system-tests/pull/3279) by @ZStriker19 and @marcotc +* 2024-10-17 [Onboarding: feature parity dashboard](https://github.com/DataDog/system-tests/pull/3247) by @robertomonteromiguel +* 2024-10-08 [Proxy exports files content in a separated folder in logs](https://github.com/DataDog/system-tests/pull/3179) by @cbeauchesne +* 2024-10-07 [External processing : initial poc](https://github.com/DataDog/system-tests/pull/3097) by @cbeauchesne and @e-n-0 + +### 2024-09 (157 PR merged) + +* 2024-09-23 [Remove legacy check on python 3.9](https://github.com/DataDog/system-tests/pull/3094) by @cbeauchesne +* 2024-09-18 [Enforce JIRA ticket in bug/flaky declarations](https://github.com/DataDog/system-tests/pull/3034) by @cbeauchesne +* 2024-09-12 [[ruby] Increment path in ruby "dev" version, and set a prerelease](https://github.com/DataDog/system-tests/pull/3022) by @cbeauchesne +* 2024-09-12 [Removes system-tests-core form owners of manifests](https://github.com/DataDog/system-tests/pull/3018) by @cbeauchesne +* 2024-09-06 [`-o xfail_strict=True` to force XPASS to fail](https://github.com/DataDog/system-tests/pull/2995) by @cbeauchesne +* 2024-09-10 [Print weblog crash logs](https://github.com/DataDog/system-tests/pull/2912) by @simon-id + + +### 2024-08 (102 PR merged) + +* 2024-08-29 [[java] Enable e2e tests on all spring-boot variants](https://github.com/DataDog/system-tests/pull/2946) by @smola +* 2024-08-22 [[java] Use HTTP interface for parametric test](https://github.com/DataDog/system-tests/pull/2869) by @cbeauchesne +* 2024-08-05 [parametric: adds a consistent interface for retrieving traces and spans](https://github.com/DataDog/system-tests/pull/2789) by @mabdinur +* 2024-08-05 [[nodejs] allow mounting local dd-trace-js as weblog volume](https://github.com/DataDog/system-tests/pull/2777) by @rochdev + + +### 2024-07 (166 PR merged) + +* 2024-07-22 [Ability to change the support state of meta struct of the agent](https://github.com/DataDog/system-tests/pull/2770) by @e-n-0 +* 2024-07-18 [Add better support for the new RC API](https://github.com/DataDog/system-tests/pull/2757) by @christophe-papazian +* 2024-07-23 [Start containers in parallel](https://github.com/DataDog/system-tests/pull/2732) by @rochdev +* 2024-07-10 [New Remote Config testing API](https://github.com/DataDog/system-tests/pull/2719) by @cbeauchesne +* 2024-07-02 [OnBoarding: Host and container guardrail testing](https://github.com/DataDog/system-tests/pull/2647) by @robertomonteromiguel + + +### 2024-06 (92 PR merged) + +* 2024-06-26 [add pytest-split to allow splitting test running in groups](https://github.com/DataDog/system-tests/pull/2589) by @rochdev +* 2024-06-24 [Remote config test API](https://github.com/DataDog/system-tests/pull/2586) by @cbeauchesne +* 2024-06-20 [[golang] Enable RASP SSRF tests](https://github.com/DataDog/system-tests/pull/2576) by @eliottness +* 2024-06-24 [RASP SQLi: enhance test & activate for Go](https://github.com/DataDog/system-tests/pull/2574) by @Hellzy +* 2024-06-19 [[go] implement RASP endpoints](https://github.com/DataDog/system-tests/pull/2551) by @eliottness +* 2024-06-03 [[python] RASP sqli tests for python](https://github.com/DataDog/system-tests/pull/2514) by @christophe-papazian + + ### 2024-05 (90 PR merged) * 2024-05-27 [Use semver for version parser](https://github.com/DataDog/system-tests/pull/2487) by @cbeauchesne @@ -21,7 +78,6 @@ All notable changes to this project will be documented in this file. ### 2024-03 (85 PR merged) -* 2024-03-29 [Fix test that triggers false XPASS](https://github.com/DataDog/system-tests/pull/2281) by @cbeauchesne * 2024-03-27 [Add more ruby variants](https://github.com/DataDog/system-tests/pull/2246) by @lloeki * 2024-03-20 [New Ruby variant : Rails 7.1](https://github.com/DataDog/system-tests/pull/2242) by @lloeki * 2024-03-18 [Add OTel Interoperability System tests](https://github.com/DataDog/system-tests/pull/2128) by @PROFeNoM @@ -39,7 +95,6 @@ All notable changes to this project will be documented in this file. ### 2024-01 (86 PR merged) -* 2024-01-31 [Remove entirely the coverage decorator](https://github.com/DataDog/system-tests/pull/2091) by @cbeauchesne * 2024-01-29 [Check variant names in manifest validation](https://github.com/DataDog/system-tests/pull/2082) by @cbeauchesne * 2024-01-29 [Generate buddies on merge if needed](https://github.com/DataDog/system-tests/pull/2068) by @robertomonteromiguel * 2024-01-15 [Support for PHP unified client library](https://github.com/DataDog/system-tests/pull/1998) by @robertomonteromiguel @@ -48,7 +103,6 @@ All notable changes to this project will be documented in this file. ### December 2023 (75 PR merged) -* 2023-12-26 [Remove legacy coverage decorator](https://github.com/DataDog/system-tests/pull/1961) by @cbeauchesne (Testing coverage is not dependant of system-tests only, so it's now declared directly in Feature Parity Dashbaord) * 2023-12-27 Declare lot of features ID ([1](https://github.com/DataDog/system-tests/pull/1968), [2](https://github.com/DataDog/system-tests/pull/1952), [3](https://github.com/DataDog/system-tests/pull/1967), [4](https://github.com/DataDog/system-tests/pull/1928), [5](https://github.com/DataDog/system-tests/pull/1915), [6](https://github.com/DataDog/system-tests/pull/1910), [7](https://github.com/DataDog/system-tests/pull/1901)) by @cbeauchesne * 2023-12-01 [Add "features" decorator](https://github.com/DataDog/system-tests/pull/1883), and [ensure in CI that all tests has a features decorator](https://github.com/DataDog/system-tests/pull/1923) by @cbeauchesne * 2023-12-27 Parametric: allow to test dev version for [python](https://github.com/DataDog/system-tests/pull/1959), [java](https://github.com/DataDog/system-tests/pull/1937), [nodejs](https://github.com/DataDog/system-tests/pull/1941) and [golang](https://github.com/DataDog/system-tests/pull/1948) by @robertomonteromiguel diff --git a/README.md b/README.md index d026674df8f..cef80a3e64e 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,58 @@ -## System tests +## What is system-tests? -Workbench designed to run advanced tests (integration, smoke, functionnal, fuzzing and performance) +A workbench designed to run advanced tests (integration, smoke, functional, fuzzing and performance) against our suite of dd-trace libraries. ## Requirements -`bash`, `docker` and `python3.9`. More infos in the [documentation](https://github.com/DataDog/system-tests/blob/main/docs/execute/requirements.md) +`bash`, `docker` and `python3.12`. -## How to use +We recommend to install python3.12 via pyenv: [pyenv](https://github.com/pyenv/pyenv#getting-pyenv). Pyenv is a tool for managing multiple python versions and keeping system tests dependencies isolated to their virtual environment. If you don't wish to install pyenv, instructions for downloading python 3.12 on your machine can be found below: -Add a valid staging `DD_API_KEY` environment variable (you can set it in a `.env` file). Then: +#### Ubuntu + +``` +sudo add-apt-repository ppa:deadsnakes/ppa +sudo apt update +sudo apt install python3.12 python3.12-distutils python3.12-venv python3.12-dev +curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py +python3.12 get-pip.py +./build.sh -i runner +``` + +#### Windows + +TODO + +#### Mac + +For Homebrew users : + +``` +brew install python@3.12 +pip3.12 install virtualenv +``` + +## Getting started + +### Run a test + +Run a test according to the [run documentation](docs/execute/run.md); note that if you're running an [end to end test](docs/scenarios/README.md#end-to-end-scenarios), you will need to build the test infrastructure according to the [build documentation](docs/execute/build.md) before you can run the test. + +Tests will only run if they are not disabled; see how tests are disabled in [skip-tests.md](docs/edit/skip-tests.md) and how tests are enabled in [enable-test.md](docs/edit/enable-test.md). Alternatively, you can force a disabled test to execute according to the [force-execute documentation](docs/execute/force-execute.md). + +![Output on success](./utils/assets/output.png?raw=true) + +### Edit a test + +Refer to the [edit docs](docs/edit/README.md). + +### Understand the tests + +**[Complete documentation](https://github.com/DataDog/system-tests/blob/main/docs)** + +System-tests supports various scenarios for running tests; read more about the different kinds of tests that this repo covers in [scenarios/README.md](docs/scenarios/README.md). + +Understand the test architecture at the [architectural overview](https://github.com/DataDog/system-tests/blob/main/docs/architecture/overview.md). ```mermaid flowchart TD @@ -26,12 +70,3 @@ flowchart TD OUTPUT[Test output in bash] LOGS[Logs directory per scenario] ``` - -Understand the parts of the tests at the [architectural overview](https://github.com/DataDog/system-tests/blob/main/docs/architecture/overview.md). - -More details in [build documentation](https://github.com/DataDog/system-tests/blob/main/docs/execute/build.md) and [run documentation](https://github.com/DataDog/system-tests/blob/main/docs/execute/run.md). - -![Output on success](./utils/assets/output.png?raw=true) - -**[Complete documentation](https://github.com/DataDog/system-tests/blob/main/docs)** - diff --git a/conftest.py b/conftest.py index b67aef1a1de..2bcd14ad5e1 100644 --- a/conftest.py +++ b/conftest.py @@ -15,13 +15,15 @@ from utils.tools import logger from utils.scripts.junit_report import junit_modifyreport from utils._context.library_version import LibraryVersion -from utils._decorators import released +from utils._decorators import released, configure as configure_decorators +from utils.properties_serialization import SetupProperties # Monkey patch JSON-report plugin to avoid noise in report -JSONReport.pytest_terminal_summary = lambda *args, **kwargs: None +JSONReport.pytest_terminal_summary = lambda *args, **kwargs: None # noqa: ARG005 # pytest does not keep a trace of deselected items, so we keep it in a global variable _deselected_items = [] +setup_properties = SetupProperties() def pytest_addoption(parser): @@ -34,6 +36,22 @@ def pytest_addoption(parser): "--force-execute", "-F", action="append", default=[], help="Item to execute, even if they are skipped" ) parser.addoption("--scenario-report", action="store_true", help="Produce a report on nodeids and their scenario") + parser.addoption( + "--skip-empty-scenario", + action="store_true", + help="Skip scenario if it contains only tests marked as xfail or irrelevant", + ) + + parser.addoption("--force-dd-trace-debug", action="store_true", help="Set DD_TRACE_DEBUG to true") + parser.addoption("--force-dd-iast-debug", action="store_true", help="Set DD_IAST_DEBUG_ENABLED to true") + # k8s scenarios mandatory parameters + parser.addoption("--k8s-weblog", type=str, action="store", help="Set weblog to deploy on k8s") + parser.addoption("--k8s-library", type=str, action="store", help="Set language to test") + parser.addoption( + "--k8s-lib-init-img", type=str, action="store", help="Set tracers init image on the docker registry" + ) + parser.addoption("--k8s-weblog-img", type=str, action="store", help="Set test app image on the docker registry") + parser.addoption("--k8s-cluster-version", type=str, action="store", help="Set the datadog agent version") # Onboarding scenarios mandatory parameters parser.addoption("--vm-weblog", type=str, action="store", help="Set virtual machine weblog") @@ -41,18 +59,66 @@ def pytest_addoption(parser): parser.addoption("--vm-env", type=str, action="store", help="Set virtual machine environment") parser.addoption("--vm-provider", type=str, action="store", help="Set provider for VMs") parser.addoption("--vm-only-branch", type=str, action="store", help="Filter to execute only one vm branch") + parser.addoption("--vm-only", type=str, action="store", help="Filter to execute only one vm name") parser.addoption("--vm-skip-branches", type=str, action="store", help="Filter exclude vm branches") + parser.addoption( + "--vm-gitlab-pipeline", + type=str, + action="store", + help="Generate pipeline for Gitlab CI. Not run the tests. Values: one-pipeline, system-tests", + ) + + parser.addoption( + "--vm-default-vms", + type=str, + action="store", + help="True launch vms marked as default, False launch only no default vm. All launch all vms", + default="True", + ) + + # Docker ssi scenarios + parser.addoption("--ssi-weblog", type=str, action="store", help="Set docker ssi weblog") + parser.addoption("--ssi-library", type=str, action="store", help="Set docker ssi library to test") + parser.addoption("--ssi-base-image", type=str, action="store", help="Set docker ssi base image to build") + parser.addoption("--ssi-arch", type=str, action="store", help="Set docker ssi archictecture of the base image") + parser.addoption( + "--ssi-installable-runtime", + type=str, + action="store", + help=( + """Set the language runtime to install on the docker base image. """ + """Empty if we don't want to install any runtime""" + ), + ) + parser.addoption("--ssi-push-base-images", "-P", action="store_true", help="Push docker ssi base images") + parser.addoption("--ssi-force-build", "-B", action="store_true", help="Force build ssi base images") + + # Parametric scenario options + parser.addoption( + "--library", + "-L", + type=str, + action="store", + default="", + help="Library to test (e.g. 'python', 'ruby')", + choices=["cpp", "golang", "dotnet", "java", "nodejs", "php", "python", "ruby"], + ) # report data to feature parity dashboard parser.addoption( - "--report-run-url", type=str, action="store", default=None, help="URI of the run who produced the report", + "--report-run-url", type=str, action="store", default=None, help="URI of the run who produced the report" ) parser.addoption( - "--report-environment", type=str, action="store", default=None, help="The environment the test is run under", + "--report-environment", type=str, action="store", default=None, help="The environment the test is run under" ) def pytest_configure(config): + if not config.option.force_dd_trace_debug and os.environ.get("SYSTEM_TESTS_FORCE_DD_TRACE_DEBUG") == "true": + config.option.force_dd_trace_debug = True + + if not config.option.force_dd_iast_debug and os.environ.get("SYSTEM_TESTS_FORCE_DD_IAST_DEBUG") == "true": + config.option.force_dd_iast_debug = True # handle options that can be filled by environ if not config.option.report_environment and "SYSTEM_TESTS_REPORT_ENVIRONMENT" in os.environ: @@ -61,6 +127,12 @@ def pytest_configure(config): if not config.option.report_run_url and "SYSTEM_TESTS_REPORT_RUN_URL" in os.environ: config.option.report_run_url = os.environ["SYSTEM_TESTS_REPORT_RUN_URL"] + if ( + not config.option.skip_empty_scenario + and os.environ.get("SYSTEM_TESTS_SKIP_EMPTY_SCENARIO", "").lower() == "true" + ): + config.option.skip_empty_scenario = True + # First of all, we must get the current scenario for name in dir(scenarios): if name.upper() == config.option.scenario: @@ -68,35 +140,34 @@ def pytest_configure(config): break if context.scenario is None: - pytest.exit(f"Scenario {config.option.scenario} does not exists", 1) + pytest.exit(f"Scenario {config.option.scenario} does not exist", 1) - context.scenario.configure(config) + context.scenario.pytest_configure(config) if not config.option.replay and not config.option.collectonly: config.option.json_report_file = f"{context.scenario.host_log_folder}/report.json" config.option.xmlpath = f"{context.scenario.host_log_folder}/reportJunit.xml" + configure_decorators(config) + # Called at the very begening def pytest_sessionstart(session): - # get the terminal to allow logging directly in stdout - setattr(logger, "terminal", session.config.pluginmanager.get_plugin("terminalreporter")) + logger.terminal = session.config.pluginmanager.get_plugin("terminalreporter") + + # if only collect tests, do not start the scenario + if not session.config.option.collectonly: + context.scenario.pytest_sessionstart(session) if session.config.option.sleep: logger.terminal.write("\n ********************************************************** \n") logger.terminal.write(" *** .:: Sleep mode activated. Press Ctrl+C to exit ::. *** ") logger.terminal.write("\n ********************************************************** \n\n") - if session.config.option.collectonly: - return - - context.scenario.session_start() - # called when each test item is collected def _collect_item_metadata(item): - result = { "details": None, "testDeclaration": None, @@ -110,11 +181,7 @@ def _collect_item_metadata(item): if skip_reason is not None: # if any irrelevant declaration exists, it is the one we need to expose - if skip_reason.startswith("irrelevant"): - result["details"] = skip_reason - - # otherwise, we keep the first one we found - elif result["details"] is None: + if skip_reason.startswith("irrelevant") or result["details"] is None: result["details"] = skip_reason if result["details"]: @@ -126,8 +193,13 @@ def _collect_item_metadata(item): result["testDeclaration"] = "flaky" elif result["details"].startswith("bug"): result["testDeclaration"] = "bug" + elif result["details"].startswith("incomplete_test_app"): + result["testDeclaration"] = "incompleteTestApp" elif result["details"].startswith("missing_feature"): result["testDeclaration"] = "notImplemented" + elif "got empty parameter set" in result["details"]: + # Case of a test with no parameters. Onboarding: we removed the parameter/machine with excludedBranches + logger.info(f"No parameters found for ${item.nodeid}") else: raise ValueError(f"Unexpected test declaration for {item.nodeid} : {result['details']}") @@ -149,7 +221,6 @@ def _get_skip_reason_from_marker(marker): def pytest_pycollect_makemodule(module_path, parent): - # As now, declaration only works for tracers at module level library = context.scenario.library.library @@ -158,27 +229,32 @@ def pytest_pycollect_makemodule(module_path, parent): nodeid = str(module_path.relative_to(module_path.cwd())) - if nodeid in manifests and library in manifests[nodeid]: - declaration = manifests[nodeid][library] + if nodeid not in manifests or library not in manifests[nodeid]: + return None - logger.info(f"Manifest declaration found for {nodeid}: {declaration}") + declaration: str = manifests[nodeid][library] - mod: pytest.Module = pytest.Module.from_parent(parent, path=module_path) + logger.info(f"Manifest declaration found for {nodeid}: {declaration}") - if declaration.startswith("irrelevant") or declaration.startswith("flaky"): - mod.add_marker(pytest.mark.skip(reason=declaration)) - logger.debug(f"Module {nodeid} is skipped by manifest file because {declaration}") - else: - mod.add_marker(pytest.mark.xfail(reason=declaration)) - logger.debug(f"Module {nodeid} is xfailed by manifest file because {declaration}") + mod: pytest.Module = pytest.Module.from_parent(parent, path=module_path) + + if declaration.startswith(("irrelevant", "flaky")): + mod.add_marker(pytest.mark.skip(reason=declaration)) + logger.debug(f"Module {nodeid} is skipped by manifest file because {declaration}") + else: + mod.add_marker(pytest.mark.xfail(reason=declaration)) + logger.debug(f"Module {nodeid} is xfailed by manifest file because {declaration}") - return mod + return mod @pytest.hookimpl(tryfirst=True) def pytest_pycollect_makeitem(collector, name, obj): - if collector.istestclass(obj, name): + if obj is None: + message = f"""{collector.nodeid} is not properly collected. + You may have forgotten to return a value in a decorator like @features""" + raise ValueError(message) manifest = load_manifests() @@ -188,34 +264,44 @@ def pytest_pycollect_makeitem(collector, name, obj): declaration = manifest[nodeid] logger.info(f"Manifest declaration found for {nodeid}: {declaration}") - released(**declaration)(obj) + try: + released(**declaration)(obj) + except Exception as e: + raise ValueError(f"Unexpected error for {nodeid}.") from e def pytest_collection_modifyitems(session, config, items: list[pytest.Item]): - """unselect items that are not included in the current scenario""" + """Unselect items that are not included in the current scenario""" logger.debug("pytest_collection_modifyitems") selected = [] deselected = [] - declared_scenarios = {} + all_declared_scenarios = {} def iter_markers(self, name=None): return (x[1] for x in self.iter_markers_with_node(name=name) if x[1].name not in ("skip", "skipif", "xfail")) + must_pass_item_count = 0 for item in items: - scenario_markers = list(item.iter_markers("scenario")) - declared_scenario = scenario_markers[0].args[0] if len(scenario_markers) != 0 else "DEFAULT" + # if the item has explicit scenario markers, we use them + # otherwise we use markers declared on its parents + own_markers = [marker for marker in item.own_markers if marker.name == "scenario"] + scenario_markers = own_markers if len(own_markers) != 0 else list(item.iter_markers("scenario")) + if len(scenario_markers) == 0: + declared_scenarios = ["DEFAULT"] + else: + declared_scenarios = [marker.args[0] for marker in scenario_markers] - declared_scenarios[item.nodeid] = declared_scenario + all_declared_scenarios[item.nodeid] = declared_scenarios # If we are running scenario with the option sleep, we deselect all - if session.config.option.sleep: + if session.config.option.sleep or session.config.option.vm_gitlab_pipeline: deselected.append(item) continue - if context.scenario.is_part_of(declared_scenario): + if context.scenario.name in declared_scenarios: logger.info(f"{item.nodeid} is included in {context.scenario}") selected.append(item) @@ -228,28 +314,50 @@ def iter_markers(self, name=None): # including parent's markers) to exclude the skip, skipif and xfail markers. item.iter_markers = types.MethodType(iter_markers, item) + if _item_must_pass(item): + must_pass_item_count += 1 + else: logger.debug(f"{item.nodeid} is not included in {context.scenario}") deselected.append(item) - items[:] = selected - config.hook.pytest_deselected(items=deselected) + + if must_pass_item_count == 0 and session.config.option.skip_empty_scenario: + items[:] = [] + config.hook.pytest_deselected(items=items) + else: + items[:] = selected + config.hook.pytest_deselected(items=deselected) if config.option.scenario_report: with open(f"{context.scenario.host_log_folder}/scenarios.json", "w", encoding="utf-8") as f: - json.dump(declared_scenarios, f, indent=2) + json.dump(all_declared_scenarios, f, indent=2) def pytest_deselected(items): _deselected_items.extend(items) +def _item_must_pass(item) -> bool: + """Returns True if the item must pass to be considered as a success""" + + if any(item.iter_markers("skip")): + return False + + if any(item.iter_markers("xfail")): + return False + + for marker in item.iter_markers("skipif"): + if all(marker.args[0]): + return False + + return True + + def _item_is_skipped(item): return any(item.iter_markers("skip")) -def pytest_collection_finish(session): - from utils import weblog - +def pytest_collection_finish(session: pytest.Session): if session.config.option.collectonly: return @@ -260,19 +368,19 @@ def pytest_collection_finish(session): except KeyboardInterrupt: # catching ctrl+C context.scenario.close_targets() return - except Exception as e: - raise e + + if session.config.option.replay: + setup_properties.load(context.scenario.host_log_folder) last_item_file = "" for item in session.items: - if _item_is_skipped(item): continue if not item.instance: # item is a method bounded to a class continue - # the test metohd name is like test_xxxx + # the test method name is like test_xxxx # we replace the test_ by setup_, and call it if it exists setup_method_name = f"setup_{item.name[5:]}" @@ -289,11 +397,14 @@ def pytest_collection_finish(session): last_item_file = item_file setup_method = getattr(item.instance, setup_method_name) - logger.debug(f"Call {setup_method} for {item}") try: - weblog.current_nodeid = item.nodeid - setup_method() - weblog.current_nodeid = None + if session.config.option.replay: + logger.debug(f"Restore properties of {setup_method} for {item}") + setup_properties.restore_properties(item) + else: + logger.debug(f"Call {setup_method} for {item}") + setup_method() + setup_properties.store_properties(item) except Exception: logger.exception("Unexpected failure during setup method call") logger.terminal.write("x", bold=True, red=True) @@ -301,29 +412,22 @@ def pytest_collection_finish(session): raise else: logger.terminal.write(".", bold=True, green=True) - finally: - weblog.current_nodeid = None logger.terminal.write("\n\n") - context.scenario.post_setup() + if not session.config.option.replay: + setup_properties.dump(context.scenario.host_log_folder) + context.scenario.post_setup(session) -def pytest_runtest_call(item): - from utils import weblog - if item.nodeid in weblog.responses: - for response in weblog.responses[item.nodeid]: - request = response["request"] - if "method" in request: - logger.info(f"weblog {request['method']} {request['url']} -> {response['status_code']}") - else: - logger.info("weblog GRPC request") +def pytest_runtest_call(item): + # add a log line for each request made by the setup, to help debugging + setup_properties.log_requests(item) @pytest.hookimpl(optionalhook=True) def pytest_json_runtest_metadata(item, call): - if call.when != "setup": return {} @@ -331,7 +435,6 @@ def pytest_json_runtest_metadata(item, call): def pytest_json_modifyreport(json_report): - try: # add usefull data for reporting json_report["context"] = context.serialize() @@ -343,29 +446,45 @@ def pytest_json_modifyreport(json_report): def pytest_sessionfinish(session, exitstatus): + logger.info("Executing pytest_sessionfinish") + + if session.config.option.skip_empty_scenario and exitstatus == pytest.ExitCode.NO_TESTS_COLLECTED: + exitstatus = pytest.ExitCode.OK + session.exitstatus = pytest.ExitCode.OK + + context.scenario.pytest_sessionfinish(session, exitstatus) - context.scenario.pytest_sessionfinish(session) if session.config.option.collectonly or session.config.option.replay: return # xdist: pytest_sessionfinish function runs at the end of all tests. If you check for the worker input attribute, # it will run in the master thread after all other processes have finished testing - if not hasattr(session.config, "workerinput"): + if context.scenario.is_main_worker: with open(f"{context.scenario.host_log_folder}/known_versions.json", "w", encoding="utf-8") as f: json.dump( - {library: sorted(versions) for library, versions in LibraryVersion.known_versions.items()}, f, indent=2, + {library: sorted(versions) for library, versions in LibraryVersion.known_versions.items()}, f, indent=2 ) - data = session.config._json_report.report # pylint: disable=protected-access + data = session.config._json_report.report # noqa: SLF001 - junit_modifyreport( - data, session.config.option.xmlpath, junit_properties=context.scenario.get_junit_properties(), - ) + try: + junit_modifyreport( + data, session.config.option.xmlpath, junit_properties=context.scenario.get_junit_properties() + ) - export_feature_parity_dashboard(session, data) + export_feature_parity_dashboard(session, data) + except Exception: + logger.exception("Fail to export export reports", exc_info=True) + + if session.config.option.vm_gitlab_pipeline: + NO_TESTS_COLLECTED = 5 # noqa: N806 + SUCCESS = 0 # noqa: N806 + if exitstatus == NO_TESTS_COLLECTED: + session.exitstatus = SUCCESS def export_feature_parity_dashboard(session, data): + tests = [convert_test_to_feature_parity_model(test) for test in data["tests"]] result = { "runUrl": session.config.option.report_run_url or "https://github.com/DataDog/system-tests", @@ -373,12 +492,13 @@ def export_feature_parity_dashboard(session, data): "environment": session.config.option.report_environment or "local", "testSource": "systemtests", "language": context.scenario.library.library, - "variant": context.scenario.weblog_variant, + "variant": context.weblog_variant, "testedDependencies": [ {"name": name, "version": str(version)} for name, version in context.scenario.components.items() ], + "configuration": context.configuration, "scenario": context.scenario.name, - "tests": [convert_test_to_feature_parity_model(test) for test in data["tests"]], + "tests": [test for test in tests if test is not None], } context.scenario.customize_feature_parity_dashboard(result) with open(f"{context.scenario.host_log_folder}/feature_parity.json", "w", encoding="utf-8") as f: @@ -395,7 +515,8 @@ def convert_test_to_feature_parity_model(test): "features": test["metadata"]["features"], } - return result + # exclude features.not_reported + return result if -1 not in result["features"] else None ## Fixtures corners diff --git a/default.nix b/default.nix new file mode 100644 index 00000000000..f8629f43ba0 --- /dev/null +++ b/default.nix @@ -0,0 +1,12 @@ +# flake-compat shim for usage without flakes +(import + ( + let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in + fetchTarball { + url = lock.nodes.flake-compat.locked.url or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } + ) + { src = ./.; } +).defaultNix + diff --git a/docs/CI/README.md b/docs/CI/README.md index 7cf4e5745db..db4d5473cd3 100644 --- a/docs/CI/README.md +++ b/docs/CI/README.md @@ -2,9 +2,7 @@ All information you need to add System Tests in your CI. ## How to integrate in a CI? -You'll need a CI that with `docker` and `python 3.9` installed, among with very common UNIX tools. - -A valid `DD_API_KEY` env var for staging must be set. +You'll need a CI that with `docker` and `python 3.12` installed, among with very common UNIX tools. 1. Clone this repo 2. Copy paste your components' build inside `./binaries` (See [documentation](./binaries.md)) diff --git a/docs/CI/github-actions.md b/docs/CI/github-actions.md index 6ea8a0c7e6e..c29d5e685c9 100644 --- a/docs/CI/github-actions.md +++ b/docs/CI/github-actions.md @@ -1,9 +1,4 @@ -First of all, add two secrets: - -1. a valid github token in `GH_TOKEN` -1. a valid staging API key token in `DD_API_KEY` - -Then, add a file in your repo named `.github/workflows/system-tests.yml`: +Add a file in your repo named `.github/workflows/system-tests.yml`: ```yaml name: System Tests @@ -22,16 +17,12 @@ jobs: - library: golang weblog-variant: net-http fail-fast: false - env: - TEST_LIBRARY: ${{ matrix.library }} - WEBLOG_VARIANT: ${{ matrix.weblog-variant }} - DD_API_KEY: ${{ secrets.DD_API_KEY }} steps: - name: Checkout uses: actions/checkout@v4 with: repository: 'DataDog/system-tests' - token: ${{ secrets.GH_TOKEN }} + persist_credentials: false - name: Get component binary # you need to copy a valid binary of your component inside binaries/ folder. @@ -39,7 +30,7 @@ jobs: run: <...> - name: Build - run: ./build.sh + run: ./build.sh ${{ matrix.library }} -w ${{ matrix.weblog-variant }} - name: Run run: ./run.sh diff --git a/docs/CI/gitlab-ci.md b/docs/CI/gitlab-ci.md index 62db91a6708..8a44962cbd0 100644 --- a/docs/CI/gitlab-ci.md +++ b/docs/CI/gitlab-ci.md @@ -4,12 +4,10 @@ 1. Install aws-cli 2. Save a valid github PATH token in a file named GH_TOKEN -3. Save a valid staging API key in a file named DD_API_KEY -4. then execute +3. then execute ``` aws-vault exec --debug build-stable-developer # Enter a token from your MFA device unset AWS_VAULT -cat DD_API_KEY | aws-vault exec build-stable-developer -- ci-secrets set ci.system-tests.dd_api_key cat GH_TOKEN | aws-vault exec build-stable-developer -- ci-secrets set ci.system-tests.gh_token ``` diff --git a/docs/RC/RC-API.md b/docs/RC/RC-API.md deleted file mode 100644 index 51914874fde..00000000000 --- a/docs/RC/RC-API.md +++ /dev/null @@ -1,42 +0,0 @@ -The RC API is the official way to interact with remote config. It allows to send RC payload to the library durint setup phase, and send request before/after each state change. Here is an example a scenario activating/deactivating ASM: - -1. the library starts in an initial state where ASM is disabled. This state is validated with an assertion on a request containing an attack : the request should not been caught by ASM -2. Then a RC command is sent to activate ASM -3. another request containing an attack is sent, this one must be reported by ASM -4. A second command is sent to deactivate ASM -5. a thirst request containing an attack is sent, this last one should not be seen - - -Here is the test code performing that test. Please note the magic constants `ACTIVATE_ASM_PAYLOAD` and `DEACTIVATE_ASM_PAYLOAD`: they are encoded RC payload (exemple [here](https://github.com/DataDog/system-tests/blob/7644ceaa3c7ea44ade8bcca8c3bb2a5991d03e34/utils/proxy/rc_mocked_responses_asm_activate_only.json)). We still miss a tool that generate them from human-readable content, it will come in a near future. - -```python -from utils import weblog, interfaces, scenarios, remote_config - - -@scenarios.asm_deactivated # in this scenario, ASM is deactivated -class Test_RemoteConfigSequence: - """ Test that ASM can be activated/deacrivated using Remote Config """ - - def setup_asm_switch_on_switch_off(self): - # at initiation, ASM is disabled - self.first_request = weblog.get("/waf/", headers={"User-Agent": "Arachni/v1"}) - - # this function will send a RC payload to the library, and wait for a confirmation from the library - self.config_state_activation = remote_config.send_command(raw_payload=ACTIVATE_ASM_PAYLOAD) - self.second_request = weblog.get("/waf/", headers={"User-Agent": "Arachni/v1"}) - - # now deactivate the WAF, and check that it does not catch anything - self.config_state_deactivation = remote_config.send_command(raw_payload=DEACTIVATE_ASM_PAYLOAD) - self.third_request = weblog.get("/waf/", headers={"User-Agent": "Arachni/v1"}) - - def test_asm_switch_on_switch_off(): - # first check that both config state are ok, otherwise, next assertions will fail with cryptic messages - assert self.config_state_activation["apply_state"] == remote_config.ApplyState.ACKNOWLEDGED, self.config_state_activation - assert self.config_state_deactivation["apply_state"] == remote_config.ApplyState.ACKNOWLEDGED, self.config_state_deactivation - - interfaces.library.assert_no_appsec_event(self.first_request) - interfaces.library.assert_waf_attack(self.second_request) - interfaces.library.assert_no_appsec_event(self.third_request) -``` - -To use this feature, you must use an `EndToEndScenario` with `rc_api_enabled=True`. diff --git a/docs/RC/README.md b/docs/RC/README.md deleted file mode 100644 index 682af79ddcf..00000000000 --- a/docs/RC/README.md +++ /dev/null @@ -1,48 +0,0 @@ -## How to create tests with new Remote Config - -### Create new scenario - -To run tests with custom Remote Config, you need to create new scenario with a mocked RC responses. - -```python -appsec_api_security_rc = EndToEndScenario( - "APPSEC_API_SECURITY_RC", - proxy_state={"mock_remote_config_backend": "APPSEC_API_SECURITY_RC"}, - doc=""" - Scenario to test API Security Remote config - """, -) -``` -In this code example, we can see that we are defining a proxy for remote config, with the name **APPSEC_API_SECURITY_RC**, -it means that this scenario will mock calls from libraries to `/v7/config` by the content in *utils/proxy/rc_mocked_responses_**appsec_api_security_rc**.json* file. - -### Create mock file - -`utils/proxy/rc_mocked_responses_.json` JSON file contains an array with a list of the responses that config url will return. The items are returned in order, first time it returns the first element in the list, and each time the request is made, it returns the next value in the list. - -There is a repository [RC tracer client test generator](https://github.com/DataDog/rc-tracer-client-test-generator) that you can use to generate RC files. - -### Wait to RC loaded - -In your tests, you should wait until the RC is loaded. If your mock list only have one item, you can use this method to wait until RC is loaded to start executing the requests. - -```python -interfaces.library.wait_for_remote_config_request() -``` - -If you have more configs in the list, and you need to wait to one specific config, you can until the file that you need is loaded, for example, it is done in [blocked ips system test](https://github.com/DataDog/system-tests/blob/72f8b47d014977fb4cd63c64bb1f8340e01dec05/tests/appsec/test_ip_blocking_full_denylist.py#L56-L68). - -```python -def remote_config_is_applied(data): - if data["path"] == "/v0.7/config": - if "config_states" in data.get("request", {}).get("content", {}).get("client", {}).get("state", {}): - config_states = data["request"]["content"]["client"]["state"]["config_states"] - - for state in config_states: - if state["id"] == "ASM_DATA-third": - return True - - return False - -interfaces.library.wait_for(remote_config_is_applied, timeout=30) -``` \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 4e080c3ab87..61b206d2355 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,7 +7,7 @@ System tests is a test workbench that allows any kind of functional testing over ## How to run them locally? -You will only need `docker-compose`. It's basically cloning this repo, create a `.env` file with `DD_API_KEY=` and run two commands. Please have a look at the [execution documentation](./execute). +You will only need `python3.12`. It's basically cloning this repo and run two commands. Please have a look at the [execution documentation](./execute). ## How to add them to a CI? diff --git a/docs/RFCs/manifest.md b/docs/RFCs/manifest.md index 94d827bbffa..aa5a67c3a9f 100644 --- a/docs/RFCs/manifest.md +++ b/docs/RFCs/manifest.md @@ -135,7 +135,7 @@ tests/: "skipped_declaration": { "type": "string", - "pattern": "^(bug|flaky|irrelevant|missing_feature)( \\(.+\\))?$" + "pattern": "^(bug|flaky|irrelevant|missing_feature|incomplete_test_app)( \\(.+\\))?$" } } } diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md index c771e6dd4fe..548a4e4c79e 100644 --- a/docs/architecture/overview.md +++ b/docs/architecture/overview.md @@ -111,11 +111,11 @@ flowchart TD The `./run.sh` script starts the containers in the background. -Often, knowing how a container fails to start is as simple as running `docker-compose up {container}` and observing the output. +Often, knowing how a container fails to start is as simple as adding `--sleep` to your `run` command and observing the output. If there are more in depth problems within a container you may need to adjust the Dockerfile. - re-run `./build.sh` - - start the container via `docker-compose up` + - start the container via `./run.sh --sleep` - `docker exec -it {container-id} bash` to diagnose from within the container ## What is the structure of the code base? @@ -185,8 +185,6 @@ It is a web application that exposes consistent endpoints across all implementat If you are introducing a new Dockerfile, or looking to modify an existing one, remember that they are built using this convention in arguments: `./utils/build/docker/{language}/{dockerfile-prefix}.Dockerfile`. -All application containers share final layers applied via this file: `./utils/build/docker/set-system-tests-weblog-env.Dockerfile` - The shared application docker file is a good place to add any configuration needed across languages and variants. ## Application Proxy Container diff --git a/docs/architecture/test_template.py b/docs/architecture/test_template.py index 801114e7e41..4ffd14fd19b 100644 --- a/docs/architecture/test_template.py +++ b/docs/architecture/test_template.py @@ -2,7 +2,7 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import weblog, interfaces, context, irrelevant +from utils import weblog, interfaces # *ATTENTION*: Copy this file to the tests folder, modify, and rename with a prefix of `test_` to enable your new tests @@ -15,6 +15,7 @@ # - Skip for every library except one # @irrelevant(context.library = "dotnet", reason="only for .NET") + # To run an individual test: ./run.sh tests/test_traces.py::Test_Misc::test_main class Test_Misc: """*ATTENTION*: This is where you summarize the test""" diff --git a/docs/edit/README.md b/docs/edit/README.md index 98215573b27..d1976cf8f82 100644 --- a/docs/edit/README.md +++ b/docs/edit/README.md @@ -1,62 +1,31 @@ -## Run the test loccally +System tests allow developers define scenarios and ensure datadog libraries produce consistent telemetry (that is, traces, metrics, profiles, etc...). This "edit" section addresses the following use-cases: -Please have a look on the [weblog](../execute/) +1. Adding a new test (maybe to support a new or existing feature) +2. Modifying an existing test, whether that's modifying the test client (test*.py files) or the weblog and/or parametric apps that serve the test client requests) +3. Enabling/disabling tests for libraries under various conditions -```bash -./build.sh python # or any another library. This step can be ran only once, as long as you do not need a modification on the lib/agent -./run.sh -``` +**Note: Anytime you make changes and open a PR, re-run the linter**: [format.md](docs/edit/format.md) -That's it. If you're using VScode with Python extension, your terminal will automatically switch to the virtual env, and you will be able to use lint/format tools. +To make changes, you must be able to run tests locally. Instructions for running **end-to-end** tests can be found [here](https://github.com/DataDog/system-tests/blob/main/docs/execute/README.md#run-tests) and for **parametric**, [here](https://github.com/DataDog/system-tests/blob/main/docs/scenarios/parametric.md#running-the-tests). -## Propose a modification +**Note** -The workflow is very simple: add your test case, commit into a branch and create a PR. We'll review it ASAP. +For information on contributing to specifically **parametric** scenario, see [here](/docs/scenarios/parametric_contributing.md). -Depending of how far is your test from an existing tests, it'll ask you some effort. The very first step is to add it and execute it. For instance, in a new file `tests/test_some_feature.py`: +**Callout** -```python -class Test_Feature(): - def test_feature_detail(self): - assert 1 + 1 == 2 -``` +You'll commonly need to run unmerged changes to your library against system tests (e.g. to ensure the feature is up to spec). Instructions for testing against unmerged changes can be found in [enable-test.md](./enable-test.md). -Please note that you don't have to rebuild images at each iteration. Simply re-run `run.sh`. And you can also specify the test you want to run, don't be overflooded by logs: - -``` -./run.sh tests/test_some_feature.py::Test_Feature::test_feature_detail -``` - -You now want to send something on the [weblog](../edit/weblog.md), and check it. You need to use an interface validator: - -```python -from utils import weblog, interfaces - - -class Test_Feature(): - def setup_feature_detail(self): - self.r = weblog.get("/url") - - def test_feature_detail(self): - """ tests an awesome feature """ - interfaces.library.validate_spans(self.r, lamda span: span["meta"]["http.method"] == "GET") -``` - -Sometimes [skip a test](./features.md) is needed - -```python -from utils import weblog, interfaces, context, bug - - -class Test_Feature(): - - def setup_feature_detail(self): - self.r = weblog.get("/url") - - @bug(library="ruby", reason="APPSEC-123") - def test_feature_detail(self): - """ tests an awesome feature """ - interfaces.library.validate_spans(self.r, lamda span: span["meta"]["http.method"] == "GET") -``` - -You now have the basics. It proably won't be as easy, and you may needs to dive into internals, so please do not hesitate to ask for help on slack at [#apm-shared-testing](https://dd.slack.com/archives/C025TJ4RZ8X) +## Index +1. [add-new-test.md](./add-new-test.md): Add a new test +2. [scenarios.md](./scenarios.md): Add a new scenario +3. [format.md](./format.md): Use the linter +4. [features.md](./features.md): Mark tests for the feature parity dashboard +5. [enable-test.md](./enable-test.md): Enable a test +6. [skip-tests.md](./skip-tests.md): Disable tests +7. [manifest.md](./manifest.md): How tests are marked as enabled or disabled for libraries +8. [troubleshooting.md](./troubleshooting.md) Tips for debugging +9. [iast-validations.md](./iast-validations.md): Mark tests with vulnerabilities +10. [CI-and-scenarios.md](./CI-and-scenarios.md): Understand how scenarios run in CI +11. [update-docker-images.md](./update-docker-images.md): Modify test app docker images +12. [remote-config.md](./remote-config.md): Write remote config tests diff --git a/docs/edit/add-new-test.md b/docs/edit/add-new-test.md new file mode 100644 index 00000000000..0a1b8a60a7e --- /dev/null +++ b/docs/edit/add-new-test.md @@ -0,0 +1,69 @@ +Whether it's adding a new test or modifying an existing test, a moderate amount of effort will be required. The instructions below cater to end-to-end tests, refer to [the parametric contributing doc](/docs/scenarios/parametric_contributing.md)for parametric-specific instructions. + +Once the changes are complete, post them in a PR. + +#### Notes +* Each test class tests only one feature +* A test class can have several tests +* If an RFC for the feature exists, you must use the decorator `rfc` decorator: +```python +from utils import rfc + + +@rfc("http://www.claymath.org/millennium-problems") +class Test_Millenium: + """ Test on small details """ +``` + +In most cases, you'll only need to add a new test class or function. But if you need to add a new scenario, refer to [scenarios.md](./scenarios.md). + +--- + +Tests live under the `tests/` folder. You may need to add a new file to this folder, or a new directory + file to this folder. Alternatively, you may add a test to an existing file, if it makes sense. Tests are structured like so, e.g. `tests/test_some_feature.py`: + +```python +class Test_Feature(): + def optional_test_setup(self): + my_var = 1 + def test_feature_detail(self): + assert my_var + 1 == 2 +``` + +The weblog apps are responsible for generating instrumentation. Your test should send a request to the weblog and inspect the response. There are various endpoints on weblogs for performing dedicated behaviors (e.g, starting a span, etc). When writing a new test, you might use one of the existing endpoints or create a new one if needed. To validate the response from the weblog, you can use an interface validator: + +```python +from utils import weblog, interfaces + + +class Test_Feature(): + def setup_feature_detail(self): + self.r = weblog.get("/url") + + def test_feature_detail(self): + """ tests an awesome feature """ + interfaces.library.validate_spans(self.r, lamda span: span["meta"]["http.method"] == "GET") +``` + +Sometimes you need to [skip a test](./skip-tests.md): + +```python +from utils import weblog, interfaces, context, bug + + +class Test_Feature(): + + def setup_feature_detail(self): + self.r = weblog.get("/url") + + @bug(library="ruby", reason="APPSEC-123") + def test_feature_detail(self): + """ tests an awesome feature """ + interfaces.library.validate_spans(self.r, lamda span: span["meta"]["http.method"] == "GET") +``` + +You'll need to build the images at least once, so if you haven't yet, run the `build` command. After the first build, you can just re-run the tests using the `run` command. + +- build: `build.sh [options...]`, see [build documentation](../execute/build.md) for more info +- run: `./run.sh tests/test_some_feature.py::Test_Feature::test_feature_detail`, see [run documentation](../execute/run.md) for more info + +You now have the basics. Expect to dive into the test internals, but feel free to ask for help on slack at [#apm-shared-testing](https://dd.slack.com/archives/C025TJ4RZ8X) diff --git a/docs/edit/add-test-class.md b/docs/edit/add-test-class.md deleted file mode 100644 index 17a78dd72ee..00000000000 --- a/docs/edit/add-test-class.md +++ /dev/null @@ -1,22 +0,0 @@ -When you add a test class (see [features](./features.md)), you need to declare what feature it belongs to in the [Feature Parity Dashbaord](https://feature-parity.us1.prod.dog/). To achieve that, use `@features` decorators : - - -```python -@features.awesome_tests -class Test_AwesomeFeature: - """ Short description of Awesome feature """ -``` - -## Use case 1: The feature already exists - -The link to the feature is in the docstring: hover the name, this link will show up. - -## Use case 2: the feature does not exists - -1. Create it in [Feature Parity Dashbaord](https://feature-parity.us1.prod.dog/) -2. pick its feature ID (the number in the URL) -3. copy pasta in `utils/_features.py` (its straightforward) - ----- - -If you need any help, please ask on [slack](https://dd.enterprise.slack.com/archives/C025TJ4RZ8X) diff --git a/docs/edit/egg-chicken-changes.md b/docs/edit/egg-chicken-changes.md deleted file mode 100644 index 607d94aadd1..00000000000 --- a/docs/edit/egg-chicken-changes.md +++ /dev/null @@ -1,44 +0,0 @@ -As system-tests lives in a different repo, testing a new feature before merging it is not as straightforward as if the test suite was in your own repo. You must make your changes on both repo, and, if we were in a perfect world, merge them simultaneously. - -We are not in a perfect world, so here is the recipes : - -## The very lazy way - -1. Do your PR in your repo, merge it -2. Do the PR on system-tests, merge it - -Totally acceptable, if you accept the risk to do another PR on your repo. - -## The lazy way (but probably the best one) - -1. Do a PR in system-tests (it fails) -2. Do your PR in your repo -3. Test it locally -4. Merge your PR on your repo -5. Re-run system-tests PR. In theory, it should be ok. -6. Merge it - -You have to run system-tests locally. But you will reduces the risk of rework on your repo, and you keep your `main` branch clean. - -## The good way (actually good only if you don't need to modify the test) - -Use the [`-F` option](../execute/force-execute.md): - -1. If needed, add the test in system tests, skip it using manifest, merge this PR -2. Do your PR in your repo -3. Modify your CI to include the test you want to activate: - * `./run.sh MY_SCENARIO -F tests/feature.py::Test_Feature` -3. Iterate on your PR, merge it -4. :warning: Add a PR in system-tests repo to unskip the test in manifest file, otherwise we may change the test, and break your CI without noticing it. - -And so time to time, removes all the `-F` in your CI. - -## The good way (but so heavy, it's probably not worthy) - -1. Do a PR in system-tests (it fails) -2. Do your PR in your repo. **On this PR, change the CI to use the system-tests branch** -3. Iterate on both PR until the PR on your repo is ok -4. Very last commit on your PR : **revert the change on your CI that used the dedicated system-tests branch** -5. Merge your PR on your repo -6. Re-run system-tests PR CI. In theory, it should be ok. -7. Merge it. diff --git a/docs/edit/enable-test.md b/docs/edit/enable-test.md new file mode 100644 index 00000000000..406a231a7fb --- /dev/null +++ b/docs/edit/enable-test.md @@ -0,0 +1,58 @@ +## Where to begin + +So, you have a branch that contains changes you'd like to test with system tests... + +**Note**: the instructions below assume that the necessary test already exists in system-tests and your weblog or parametric app has the necessary endpoint for serving the test. + +1. Post a PR to the dd-trace repo if you have not already. + +2. Test system-tests changes locally + + Before enabling/disabling a test in CI, you'll need to test the changes locally. + + **Run the test locally against production-level code**: + + Enable the test to run on the latest version. + If you know the specific release that contains the changes that allowed your lib to pass the test, and this release is not latest version, then use that version in the manifest. But don’t + lose sleep hunting down the specific version if you don’t know it, just use the latest. + + **Run the test against unmerged or unreleased changes**: + + Follow [binaries.md](https://github.com/DataDog/system-tests/blob/main/docs/execute/binaries.md) to run the app with a custom build, then [update the manifest file](./manifest.md) with the name of your lib’s main branch (probably `v-dev`, see [versions.md](https://github.com/DataDog/system-tests/blob/main/docs/edit/versions.md)). + + By now, you should have a change to a manifest file. Post a PR to system-tests with your changes (the enabled test(s) will fail in CI if you enabled the test for the main branch; the necessary change is not merged into dd-trace main yet) + +3. Merge changes into dd-trace + +4. Re-run system-tests PR + + It should be pass. Assuming it does, merge system-tests PR. + + +--- +## Alternative approaches + +In most cases, you can ignore these. + +### Approach \#1: Good only if you don't need to modify the test) + +Use the [`-F` option](../execute/force-execute.md): + +1. If needed, add the test in system tests, skip it using manifest, merge this PR +2. Do your PR in your repo +3. Modify your CI to include the test you want to activate: + * `./run.sh MY_SCENARIO -F tests/feature.py::Test_Feature` +3. Iterate on your PR, merge it +4. :warning: Add a PR in system-tests repo to unskip the test in manifest file, otherwise we may change the test, and break your CI without noticing it. + +And so time to time, removes all the `-F` in your CI. + +### Approach #2: The most robust way (but so heavy, it's probably not worthy) + +1. Do a PR in system-tests (it fails) +2. Do your PR in your repo. **On this PR, change the CI to use the system-tests branch** +3. Iterate on both PR until the PR on your repo is ok +4. Very last commit on your PR : **revert the change on your CI that used the dedicated system-tests branch** +5. Merge your PR on your repo +6. Re-run system-tests PR CI. In theory, it should be ok. +7. Merge it. diff --git a/docs/edit/features.md b/docs/edit/features.md index 8dd696cc9ec..a5f1053da7e 100644 --- a/docs/edit/features.md +++ b/docs/edit/features.md @@ -1,6 +1,6 @@ -System tests are feature-oriented. It means that "features" drives how tests are organized. +System tests are feature-oriented; put another way, tests certify which features are supported in each client library (and the supported library versions). Each test class must belong to a "feature", where "features" map to entries in the [Feature Parity Dashboard](https://feature-parity.us1.prod.dog/). We use the `@features` decorators to achieve this. -Let's take an example with a new `Awesome feature`, part of meta feature `stuffs`, so we add a new file called `tests/test_stuffs.py` and add a test class with some boilerplate code, and a basic test: +For example, you have a new feature called `Awesome feature`, which is part of a meta feature called `stuffs`. We add a new file called `tests/test_stuffs.py` and add a test class with some boilerplate code, and a basic test: ## Hello world test @@ -15,59 +15,25 @@ class Test_AwesomeFeature: Several key points: -* One class test one feature -* One class can have several tests -* Feature link to the [Feature Parity Dashbaord](https://feature-parity.us1.prod.dog/) is declared with `@features` decorators -* Files can be nested (`tests/test_product/test_stuffs.py::Test_AwesomeFeature`), and how files are organized does not make any difference. Use you common sense, or ask on [slack](https://dd.enterprise.slack.com/archives/C025TJ4RZ8X). - -## Skip tests - -Three decorators will helps you to skip some test function or class, depending on the skip reason: - -* `@irrelevant`: no need to test, the test is skipped -* `@flaky`: The feature sometimes fails, sometimes passed, the test is skipped -* `@bug`: known bug, the test is executed, and a warning is reported if it succeed -* `@missing_feature`: feature or use case is not yet implemented, the test is executed, and a warning is reported if it succeed - -They takes several arguments: - -* `condition`: boolean, tell if it's relevant or not. As it's the first argument, you can omit the arguement name -* `library`: provide library. version numbers are allowed (`java@1.2.4`) -* `weblog_variant`: if you want to skip the test for a specific weblog - -And then, an `reason` argument with mor details. It's very handy for `@bug`, the best is providing a JIRA tickets number. - +* Each new feature should be defined in [_features.py](/utils/_features.py). This consists of adding a feature in [Feature Parity Dashboard](https://feature-parity.us1.prod.dog/), get the feature id and copying one of the already added features, changing the name and the feature id in the url, and the feature number. In this case we'd add ```python -from utils import irrelevant - - -@irrelevant(library="nodejs") -class Test_AwesomeFeature: - """ Short description of Awesome feature """ - - @bug(weblog_variant="echo", reason="JIRA-666") - def test_basic(self) - assert P==NP - @missing_feature(library="java@1.2.4", reason="still an hypothesis") - def test_extended(self) - assert riemann.zetas.zeros.real == 0.5 + @staticmethod + def awesome_feature(test_object): + """ + Awesome Feature for Awesomeness - @missing_feature(reason="Maybe too soon") - def test_full(self) - assert 42 + https://feature-parity.us1.prod.dog/#/?feature=291 + """ + pytest.mark.features(feature_id=291)(test_object) + return test_object ``` -## Declare a RFC - -When the RFC exists, you must use this decorator: -```python -from utils import rfc - +* One class tests one feature +* One class can have several tests +* Files can be nested (`tests/test_product/test_stuffs.py::Test_AwesomeFeature`), and how files are organized does not make any difference. Use you common sense, or ask on [slack](https://dd.enterprise.slack.com/archives/C025TJ4RZ8X). -@rfc("http://www.claymath.org/millennium-problems") -class Test_Millenium: - """ Test on small details """ -``` +## Skip tests +See [skip-tests.md](/docs/edit/skip-tests.md) \ No newline at end of file diff --git a/docs/edit/format.md b/docs/edit/format.md index 85975296899..32a2995b92e 100644 --- a/docs/edit/format.md +++ b/docs/edit/format.md @@ -1,9 +1,10 @@ -System tests code is in python, and is linted/formated using [black](https://black.readthedocs.io/en/stable/) and [pylint](https://pylint.readthedocs.io/en/latest/). +System tests code is in python, and is linted/formated using [mypy](https://mypy.readthedocs.io/en/stable/), [black](https://black.readthedocs.io/en/stable/) and [pylint](https://pylint.readthedocs.io/en/latest/). -You'll only need [python3.9](https://www.python.org/downloads/) (you may have it by default) to run them, with a unique command : +Ensure you meet the other pre-reqs in [README.md](../../README.md#requirements) +Then, run the linter with: ```bash ./format.sh ``` -There is a good chance that all your files are correctly formated :tada:. For some use-cases where issues can't be automatically fixed, you'll jave the explanation in the output. And you can run only checks, without modifying any file using the `-c` option. +Any library app code (that is, code written in Java, Golang, .NET, etc in weblog or parametric apps) will need to be formatted using that library's formatter. diff --git a/docs/edit/manifest.md b/docs/edit/manifest.md index 291e02b0d6a..aa74c9f6002 100644 --- a/docs/edit/manifest.md +++ b/docs/edit/manifest.md @@ -1,4 +1,32 @@ -Manifest file is the usual way to declare what will be tested or not. They are located in `manifests/` folder, and every tracer team got its own manifest file. +Use the manifest files under the [manifests](../../manifests/) folder to declare what will be tested vs skipped, and under what conditions. Tests are identified by `file path` + `Test_Class_Name` +` Optional | Test_Name` (Where `Test_Name` is used to differentiate between multiple test functions within a class). +Example weblog test: +```yaml +tests/: + specific.py: v1.40.0 +``` +Example Parametric test: +```yaml +tests/: + parametric/: + specific_parametric.py: v1.40.0 +``` + +A test is **enabled** if: +- Nothing is specified in the manifest file and there aren’t conflicting in-line decorators (e.g, @bug, see [skip-tests.md](./skip-tests.md)) on the test +- `label` contains a valid [https://semver.org/] version number. +See [enable-test.md](./enable-test.md) to enable a test. + +A test is **disabled** if `label` contains some other marker. +See [skip-tests.md](./skip-tests.md) to disable a test. + +When executed locally, tests run against the latest version of dd-trace by default. In CI, the tests run against the main branch and the latest version. + +#### Notes +- Entries in the manifest file must be sorted in alphabetical order. This is validated by the TEST_THE_TESTS scenario/linter. +- Manifest files are validated using JSON schema in system tests CI +- An error will occur if a manifest file refers to a file/class that does not exists + +The example below shows a combination of options that can be deployed in manifest files. ## Example @@ -29,28 +57,9 @@ tests/: Test_FeatureE: *5_6_and_someid_backports ``` -### Implementation - -- Manifests files are inside `manifests/` folder, one per team (each library, agent, ASM rules file, any php extension...): `manifests/golang.yml`, `manifest/agent.yml`... -- Each team has ownership of its manifest file -- Manifest file are validated using JSON schema in system tests CI -- An error pops if a manifest file refers to a file/class that does not exists - -## Supported features - -- declaring a skip reason (bug, flaky, irrelevant, missing_feature) for entire file -- declaring released version (or a skip reason) for a class -- declaring released version (or a skip reason) for a class, with details for weblog variants -- The wildcard `*` is supported for weblog declarations -- Supports the full npm syntax for SemVer specification. See more at: https://github.com/npm/node-semver#ranges - -## Will never be supported: - -- any complex logic - \_ because there is not limit on the complexity. We need to draw a line based on the ratio format simplicity / number of occurrences. The cutoff point is only test classes, declaring version for weblog variants, or skip reason for the entire class. -- declaring metadata (bug, flaky, irrelevant) for test methods - - because their namings are not stable, it would lead to frequent modifications of manifest files, spaming every team - - because conflict mostly happen at class level +#### Notes +- The wildcard `*` is supported for weblog declarations. This will associate missing_feature/bug/flaky/etc. marking to all unspecified weblog variables. +- Manifests support the full npm syntax for SemVer specification. See more at: https://github.com/npm/node-semver#ranges ## Context and legacy way diff --git a/docs/edit/remote-config.md b/docs/edit/remote-config.md new file mode 100644 index 00000000000..fa742f52729 --- /dev/null +++ b/docs/edit/remote-config.md @@ -0,0 +1,157 @@ +The RC API is the official way to interact with remote config. It allows to build and send RC payloads to the library durint setup phase, and send request before/after each state change. + +## Setting RC configuration files + +### Example + +``` python +from utils import remote_config + + +# will return the global rc state +rc_state = remote_config.rc_state + +config = { + "rules_data": [ + { + "id": "blocked_ips", + "type": "ip_with_expiration", + "data": [{"value": BLOCKED_IP, "expiration": 9999999999}], + }, + ] +} + +rc_state.set_config(f"datadog/2/ASM_DATA-base/ASM_DATA-base/config", config) +# send the state to the tracer and wait for the result to be validated +rc_state.apply() +``` + +### API + +#### object `remote_config.rc_state` + + +* `set_config(self, path, config) -> rc_state` + * `path`: configuration path + * `config`: config object + + *add one configuration in the state* +* `del_config(self, path) -> rc_state` + * `path`: configuration path + + *delete one configuration in the state* +* `reset(self) -> rc_state` + + *delete all configurations in the state* +* `apply() -> tracer_state` + + *send the state using the `send_state` function (see below).* + + *return value can be used to check that the state was correctly applied to the tracer.* + +Remember that the state is shared among all tests of a scenario. +You need to reset it and apply at the start of each setup. + +## Sending states + +### Example + +Here is an example a scenario activating/deactivating ASM: + +1. the library starts in an initial state where ASM is disabled. This state is validated with an assertion on a request containing an attack : the request should not been caught by ASM +2. Then the RC state is sent to activate ASM +3. another request containing an attack is sent, this one must be reported by ASM +4. The state is modified and sent to deactivate ASM +5. a thirst request containing an attack is sent, this last one should not be seen + + +Here is the test code performing that test. Please note variables `activate_ASM_command` and `deactivate_ASM_command`: see the previous paragraph to understand how to build them. + +```python +from utils import weblog, interfaces, scenarios, remote_config + +rc_state = remote_config.rc_state + +@scenarios.asm_deactivated # in this scenario, ASM is deactivated +class Test_RemoteConfigSequence: + """ Test that ASM can be activated/deacrivated using Remote Config """ + + def setup_asm_switch_on_switch_off(self): + # at initiation, ASM is disabled + self.first_request = weblog.get("/waf/", headers={"User-Agent": "Arachni/v1"}) + + # this function will send a RC payload to the library, and wait for a confirmation from the library + self.config_states_activation = rc_state.set_config(path, asm_enabled).apply() + self.second_request = weblog.get("/waf/", headers={"User-Agent": "Arachni/v1"}) + + # now deactivate the WAF by deleting the RC file, and check that it does not catch anything + self.config_states_deactivation = rc_state.del_config(path).apply() + self.third_request = weblog.get("/waf/", headers={"User-Agent": "Arachni/v1"}) + + def test_asm_switch_on_switch_off(): + # first check that both config state are ok, otherwise, next assertions will fail with cryptic messages + assert self.config_states_activation[remote_config.RC_STATE] == remote_config.ApplyState.ACKNOWLEDGED + assert self.config_states_deactivation[remote_config.RC_STATE] == remote_config.ApplyState.ACKNOWLEDGED + # for non empty config, you can also check for details of files + assert self.config_states_activation["asm_features_activation"]["apply_state"] == remote_config.ApplyState.ACKNOWLEDGED, self.config_states_activation + + interfaces.library.assert_no_appsec_event(self.first_request) + interfaces.library.assert_waf_attack(self.second_request) + interfaces.library.assert_no_appsec_event(self.third_request) +``` + +To use this feature, you must use an `EndToEndScenario` with `rc_api_enabled=True`. + +### API + +#### `send_state(raw_payload, *, wait_for_acknowledged_status: bool = True) -> dict[str, dict[str, Any]]` + +Sends a remote config payload to the library and waits for the config to be applied. +Then returns a dictionary with the state of each requested file as returned by the library. + +The dictionary keys are the IDs from the files that can be extracted from the path, +e.g: datadog/2/ASM_FEATURES/asm_features_activation/config => asm_features_activation +and the values contain the actual state for each file: + +1. a config state acknowledging the config +2. else if not acknowledged, the last config state received +3. if no config state received, then a hardcoded one with apply_state=UNKNOWN + +Arguments: + wait_for_acknowledge_status + If True, waits for the config to be acknowledged by the library. + Else, only wait for the next request sent to /v0.7/config + +## Assertions + +During the test phase `interfaces.library` offers some helpers to perform high level assertions + +### `interfaces.library.assert_rc_apply_state` + +Check that all config_id/product have the expected apply_state returned by the library +Very simplified version of the assert_rc_targets_version_states + +* `product`: product part of the configuration path +* `config_id`: config_id part of the configuration path +* `apply_state`: expected apply_state for this config. + + +### `interfaces.library.assert_rc_targets_version_states` + +Check that for a given targets_version, the config states is the one expected + +Example : + +``` python +interfaces.library.assert_rc_targets_version_states( + targets_version=self.TARGETS_VERSION, + config_states=[ + { + "id": "ASM_DATA-base", + "version": 1, + "product": "ASM_DATA", + "apply_state": RemoteConfigApplyState.ACKNOWLEDGED.value, + } + ], +) +``` diff --git a/docs/edit/runbook.md b/docs/edit/runbook.md new file mode 100644 index 00000000000..ef52dd88f65 --- /dev/null +++ b/docs/edit/runbook.md @@ -0,0 +1,53 @@ +⚠️ Did this test just fail, and you want to fix it? ⚠️ + +Here's what you need to do! + +## test_telemetry.py + +### test_config_telemetry_completeness + +#### Summary + +This can be **easily fixed** in ~5 minutes + +This is **caused by adding a new config option** without adding the associated config normalization rules to telemetry intake + +The impact is that these **configs are not visible** in Metabase, REDAPL, or anywhere else + +#### Runbook + +1. Check the test failure to see exactly which configs are missing +2. Add config normalization rules [here](https://github.com/DataDog/dd-go/tree/prod/trace/apps/tracer-telemetry-intake/telemetry-payload/static/) following the existing pattern + 1. This can be merged with any review from [@apm-ecosystems](https://github.com/orgs/DataDog/teams/apm-ecosystems) +3. After merging, update system-tests by running [update.sh](/tests/telemetry_intake/update.sh) + 1. This can be run from the root by running `./tests/telemetry_intake/update.sh` + 2. This can be merged with any review from [@apm-ecosystems](https://github.com/orgs/DataDog/teams/apm-ecosystems) +4. You're all set - your tests should pass 🏁 + +#### Details +The specific test that failed is: + +```python +tests.test_telemetry.test_config_telemetry_completeness +``` + +This asserts that config telemetry is handled properly by telemetry intake + +Some files are manually copied from dd-go from/to the following paths using tests/telemetry_intake/update.sh +from: https://github.com/DataDog/dd-go/blob/prod/trace/apps/tracer-telemetry-intake/telemetry-payload/static/ +to: tests/telemetry_intake/static + +If this test fails, it means that a telemetry key was found in config telemetry that does not +exist in any of the files listed above in dd-go +The impact is that telemetry will not be reported to the Datadog backend won't be unusable + +To fix this, you must update dd-go to either +1) Add an exact config key to match config_norm_rules.json +2) Add a prefix that matches the config keys to config_prefix_block_list.json +3) Add a prefix rule that fits an existing prefix to config_aggregation_list.json +4) (Discouraged) Add a language-specific rule to _config_rules.json + +Once dd-go is updated, you can copy over the files to this repo and merge them in as part of your changes +This can be done by running the following from the src root + +Usage: ./tests/telemetry_intake/update.sh diff --git a/docs/edit/scenarios.md b/docs/edit/scenarios.md new file mode 100644 index 00000000000..fccac94bb7a --- /dev/null +++ b/docs/edit/scenarios.md @@ -0,0 +1,47 @@ +Current system-tests implements mostly functional end-to-end scenario. But it an achieve any test paradigm you like. Build uppon pytest, it introduces a simple - an extensible - object: `Scenario`. + +A scenario is the abstraction for a context to test, and anything can be defined inside this context. Here is the most simple context scenario you can imagine : + + +### `utils/_context/_scenarios/custom_scenario.py` + +```python +from .core import Scenario + +class CustomScenario(Scenario): + def configure(self, config): + """ + If needed, configure the context => mainly, only get infos from config + At this point, logger.stdout is unavailable, so this function should not fail, unless + there is some config error from the user + """ + + def get_warmups(self): + """ + Use this function to start anything needed to your scenario (build, run targets) + This function returns a list of callable that will be called sequentially + """ + warmups = super().get_warmups() + + warmups.append(self.start_target) + + return warmups + + def post_setup(self, session): + """ called after setup functions, and before test functions """ + + def pytest_sessionfinish(self, session, exitstatus): + """ Clean what need to be cleaned at the end of the test session """ +``` + +And include you scenario in `utils/_context/_scenarios/__init__.py` + +Then, just flag you tests classes/methods with you scenario : + +```python + +@scenarios.custom_scenario +class Test_NewStuff: + def test_main(self): + assert 1+1 == 2 +``` diff --git a/docs/edit/skip-tests.md b/docs/edit/skip-tests.md new file mode 100644 index 00000000000..6af30db2966 --- /dev/null +++ b/docs/edit/skip-tests.md @@ -0,0 +1,44 @@ +Three decorators allow you to skip test functions or classes for a library: + +* `@irrelevant`: The tested feature/behavior is irrelevant to the library, meaning the feature is either purposefully not supported by the lib or cannot reasonably be implemented +* `@missing_feature`: The tested feature/behavior does not exist in the library or there is a deficit in the test library that blocks this test from executing for the lib. **The test will be executed** and being ignored if it fails. If it passes, a warning will be added in thee output (`XPASS`) +* `@incomplete_test_app` (sublass of `missing feature`): There is a deficit in the weblog/parametric apps or testing interface that prevents us from validating a feature across different applications. +* `@bug`: The lib does not implement the feature correctly/up to spec. **The test will be executed** and being ignored if it fails. If it passes, a warning will be added in thee output (`XPASS`) +* `@flaky` (subclass of `bug`): The feature sometimes fails, sometimes passes. It's not reliable, so don't run it. + +To skip specific test functions within a test class, use them as in-line decorators (Example below). +To skip test classes or test files, use the decorator in the library's [manifest file](./manifest.md). + +The decorators take several arguments: + +* `condition`: boolean, tell if it's relevant or not. As it's the first argument, you can omit the arguement name +* `library`: provide library. version numbers are allowed e.g.`java@1.2.4`, see [versions.md](./versions.md) for more details on semantic versioning and testing against unmerged changes +* `weblog_variant`: if you want to skip the test for a specific weblog +* `reason`: why the test is skipped. It's especially useful for `@bug`, in which case the value should reference a JIRA ticket number. +* `force_skip`: if you want to not execute a test maked with `missing_feature` or `bug` (main reason it entirely break the app), you can set `force_skip` to `True` + + +```python +from utils import irrelevant, incomplete_test_app, bug, missing_feature + + +@irrelevant(library="nodejs") +class Test_AwesomeFeature: + """ Short description of Awesome feature """ + + @bug(weblog_variant="echo", reason="JIRA-666") + def test_basic(self) + assert P==NP + + @missing_feature(library="java@1.2.4", reason="still an hypothesis") + def test_extended(self) + assert riemann.zetas.zeros.real == 0.5 + + @missing_feature(reason="Maybe too soon") + def test_full(self) + assert 42 + + @incomplete_test_app(library="python", "trace/span/start endpoint does not exist") + def test_span_creation(self): + assert 68 +``` diff --git a/docs/edit/best-practices.md b/docs/edit/troubleshooting.md similarity index 100% rename from docs/edit/best-practices.md rename to docs/edit/troubleshooting.md diff --git a/docs/edit/versions.md b/docs/edit/versions.md new file mode 100644 index 00000000000..081f3a1ba58 --- /dev/null +++ b/docs/edit/versions.md @@ -0,0 +1,29 @@ +System-tests uses [SemVer](https://semver.org/), where a version is defined like: `1.2.3-prerelease+build`. + +* `1.2.3` is the trio `major`, `minor` and `patch` +* `prerelease` is an optional label, usually something like `rc1`, `dev` ... +* `build` is also an optional label, usually a commit SHA. + +Any version suffixed with a prelease is always less than the same version without the suffix: + + **`1.2.3` < `1.2.4-rc1` < `1.2.4`** + +## Use cases + +Let say your last released version is `1.2.3`, and the version of your main branch is `1.2.4-dev` (visible in system-tests output) + +### Activate a test for your last released library + +Simply use `1.2.3` + +### Activate a test for a feature just merged on a `main` branch + +* obviously, do not use `1.2.3` +* less obvious, do not use `1.2.4` ! your test won't be activated. If if you didn't implemented correctly your feature, or if a later PR break your implementation, you won't see anything before the release 😨 +* -> use `1.2.4-dev` + + +DataDog/dd-trace-js and DataDog/dd-trace-dotnet developers : as the version declared on your main branch is at the next future major, while the next version is **not** the next future major, `1.2.4` will work fine. + +DataDog/dd-trace-rb : versions of the gem are not fully semver compatible, so system-tests tries to keep all possible data. More importantly, the version declared on the main branch is not bumped (it's still `1.2.3` on the current example). So system tests increase the `patch`, and set the prerelease to `z` if it's missing. So you can safely use `1.2.4-dev`. + diff --git a/docs/edit/weblog.md b/docs/edit/weblog.md deleted file mode 100644 index 26fc9eac471..00000000000 --- a/docs/edit/weblog.md +++ /dev/null @@ -1,4 +0,0 @@ -A weblog is a simple HTTP application that ships a datadog library, and expose some endpoints. All weblog should have the same interface: - -* `/` -* `/waf` => accepts all methods, all content-type, all sub path diff --git a/docs/execute/README.md b/docs/execute/README.md index 5e0ff2daff8..26b1ca6a0d8 100644 --- a/docs/execute/README.md +++ b/docs/execute/README.md @@ -2,7 +2,7 @@ ## Run tests -You will need a bash based terminal, python3.9, git and docker. Clone this folder, and at root level, create a `.env` file with `DD_API_KEY=`. Then: +You will need a bash based terminal, python3.12, git and docker. Clone this folder, then: ```bash ./build.sh # build all images diff --git a/docs/execute/binaries.md b/docs/execute/binaries.md index 0bd749fe17f..9816ae0fc30 100644 --- a/docs/execute/binaries.md +++ b/docs/execute/binaries.md @@ -1,6 +1,6 @@ -By default, system tests will build a [weblog](../edit/weblog.md) image that ships the production version of all components. +By default, system tests will build a [weblog](../edit/weblog.md) image that ships the latest production version of the specified tracer language library. -But, obviously, testing validated versions of components is not really interesting, we need to have a way to install a specific version of at least one component. Here is recipes for each components: +But we often want to run system tests against unmerged changes. The general approach is to identify the git commit hash that contains your changes and use this commit hash to download a targeted build of the tracer. Note: ensure that the commit is pushed to a remote branch first, and when taking the commit hash, ensure you use the full hash. You can identify the commit hash using `git log` or from the github UI. ## Agent @@ -9,7 +9,13 @@ But, obviously, testing validated versions of components is not really interesti ## C++ library -* Tracer: TODO +* Tracer: +There are two ways for running the C++ library tests with a custom tracer: +1. Create a file `cpp-load-from-git` in `binaries/`. Content examples: + * `https://github.com/DataDog/dd-trace-cpp@main` + * `https://github.com/DataDog/dd-trace-cpp@` +2. Clone the dd-trace-cpp repo inside `binaries` + * Profiling: add a ddprof release tar to the binaries folder. Call the `install_ddprof`. ## .Net library @@ -22,23 +28,99 @@ But, obviously, testing validated versions of components is not really interesti ## Golang library -1. Add a file `golang-load-from-go-get`, the content will be installed by `go get`. Content example: - * `gopkg.in/DataDog/dd-trace-go.v1@master` -2. Clone the dd-trace-go repo inside `binaries` +Create a file `golang-load-from-go-get` under the `binaries` directory that specifies the target build. The content of this file will be installed by the weblog or parametric app via `go get` when the test image is built. +* Content example: + * `gopkg.in/DataDog/dd-trace-go.v1@main` Test the main branch + * `gopkg.in/DataDog/dd-trace-go.v1@v1.67.0` Test the 1.67.0 release + * `gopkg.in/DataDog/dd-trace-go.v1@` Test un-merged changes ## Java library -1. Add a valid `dd-java-agent-.jar` file in `binaries`. `` must be a valid version number. +Follow these steps to run Parametric tests with a custom Java Tracer version: + +To run a custom Tracer version from a local branch: + +1. Clone the repo and checkout to the branch you'd like to test: +```bash +git clone git@github.com:DataDog/dd-trace-java.git +cd dd-trace-java +``` +By default you will be on the `master` branch, but if you'd like to run system-tests on the changes you made to your local branch, `git checkout` to that branch before proceeding. + +2. Build Java Tracer artifacts +``` +./gradlew :dd-java-agent:shadowJar :dd-trace-api:jar +``` + +3. Copy both artifacts into the `system-tests/binaries/` folder: + * The Java tracer agent artifact `dd-java-agent-*.jar` from `dd-java-agent/build/libs/` + * Its public API `dd-trace-api-*.jar` from `dd-trace-api/build/libs/` into + +Note, you should have only TWO jar files in `system-tests/binaries`. Do NOT copy sources or javadoc jars. + +4. Run Parametric tests from the `system-tests/parametric` folder: + +```bash +TEST_LIBRARY=java ./run.sh test_span_sampling.py::test_single_rule_match_span_sampling_sss001 +``` + +To run a custom tracer version from a remote branch: + +1. Find your remote branch on Github and navigate to the `ci/circleci: build_lib` test. +2. Open the details of the test in CircleCi and click on the `Artifacts` tab. +3. Download the `libs/dd-java-agent-*-SNAPSHOT.jar` and `libs/dd-trace-api-*-SNAPSHOT.jar` and move them into the `system-tests/binaries/` folder. +4. Follow Step 4 from above to run the Parametric tests. + +Follow these steps to run the OpenTelemetry drop-in test with a custom drop-in version: + +1. Download the custom version from https://repo1.maven.org/maven2/io/opentelemetry/javaagent/instrumentation/opentelemetry-javaagent-r2dbc-1.0/ +2. Copy the downloaded `opentelemetry-javaagent-r2dbc-1.0-{version}.jar` into the `system-tests/binaries/` folder + +Then run the OpenTelemetry drop-in test from the repo root folder: + +- `./build.sh java` +- `TEST_LIBRARY=java ./run.sh INTEGRATIONS -k Test_Otel_Drop_In` ## NodeJS library -1. Create a file `nodejs-load-from-npm` in `binaries/`, the content will be installed by `npm install`. Content example: - * `DataDog/dd-trace-js#master` -2. Clone the dd-trace-js repo inside `binaries` +There are three ways to run system-tests with a custom node tracer. + +1. Using a custom tracer existing in a remote branch. + - Create a file `nodejs-load-from-npm` in `binaries/` + - In the file, add the path to the branch of the custom tracer. The content will be installed by npm install. + - Content Examples: + - `DataDog/dd-trace-js#master` + - `DataDog/dd-trace-js#` + - Run any scenario normally with `./build.sh nodejs` and `./run.sh` and your remote changes will be in effect +2. Using a custom tracer existing in a local branch. + - Create a file `nodejs-load-from-local` in `binaries/` + - In the file, add the relative path to the `dd-trace-js` repo. + - Content Examples: + - If the `dd-trace-js` repo is in the same directory as the `system-tests` repo, add `../dd-trace-js` to the file. + - This method will disable installing with npm install dd-trace and will instead get the content of the file, and use it as a location of the `dd-trace-js` repo and then mount it as a volume and npm link to it. This also removes the need to rebuild the weblog image since the code is mounted at runtime. +3. Cloning a custom tracer in `binaries` + - Clone the `dd-trace-js` repo inside `binaries`. + - Checkout the remote branch with the custom tracer in the `dd-trace-js` repo that was just cloned. + - Run any scenario normally with `./build.sh nodejs` and `./run.sh` and your remote changes will be in effect ## PHP library -1. Add a valid `.apk` file in `binaries`. +- Place `datadog-setup.php` and `dd-library-php-[X.Y.Z+commitsha]-aarch64-linux-gnu.tar.gz` (or the `x86_64` if you're not on ARM) in `/binaries` folder + - You can download those from the `build_packages/package extension` job artifacts, from a CI run of your branch. +- Copy it in the binaries folder + +Then run the tests from the repo root folder: + +- `./build.sh -i runner` +- `TEST_LIBRARY=php ./run.sh PARAMETRIC` or `TEST_LIBRARY=php ./run.sh PARAMETRIC -k ` + +> :warning: **If you are seeing DNS resolution issues when running the tests locally**, add the following config to the Docker daemon: + +```json + "dns-opts": [ + "single-request" + ], +``` ## Python library @@ -47,15 +129,27 @@ But, obviously, testing validated versions of components is not really interesti 2. Add a `.tar.gz` or a `.whl` file in `binaries`, pip will install it 3. Clone the dd-trace-py repo inside `binaries` +You can also run: +```bash +echo “ddtrace @ git+https://github.com/DataDog/dd-trace-py.git@” > binaries/python-load-from-pip +``` + ## Ruby library * Create an file `ruby-load-from-bundle-add` in `binaries/`, the content will be installed by `bundle add`. Content example: - * `gem 'ddtrace', git: "https://github.com/Datadog/dd-trace-rb", branch: "master", require: 'ddtrace/auto_instrument'` + * `gem 'datadog', git: "https://github.com/Datadog/dd-trace-rb", branch: "master", require: 'datadog/auto_instrument'` 2. Clone the dd-trace-rb repo inside `binaries` ## WAF rule set * copy a file `waf_rule_set` in `binaries/` + +#### After Testing with a Custom Tracer: +Most of the ways to run system-tests with a custom tracer version involve modifying the binaries directory. Modifying the binaries will alter the tracer version used across your local computer. Once you're done testing with the custom tracer, ensure you **remove** it. For example for Python: +```bash +rm -rf binaries/python-load-from-pip +``` + ---- Hint for components who allows to have the repo in `binaries`, use the command `mount --bind src dst` to mount your local repo => any build of system tests will uses it. diff --git a/docs/execute/build.md b/docs/execute/build.md index 26132be5c6b..d7144870caa 100644 --- a/docs/execute/build.md +++ b/docs/execute/build.md @@ -43,7 +43,7 @@ Build images used for system tests. * For `golang`: `net-http` (default), `gin`, `echo`, `chi` + Specific to the `GRAPHQL_APPSEC` scenario: `gqlgen`, `graph-gophers`, `graphql-go` * For `java`: `spring-boot` (default) -* For `nodejs`: `express4` (default), `express4-typescript`, `nextjs` +* For `nodejs`: `express4` (default), `express4-typescript`, `express5`, `nextjs` * For `php`: `apache-mod-8.1`, `apache-mod-8.0` (default), `apache-mod-7.4`, `apache-mod-7.3`, `apache-mod-7.2`, `apache-mod-7.1`, `apache-mod-7.0`, `apache-mod-8.1-zts`, `apache-mod-8.0-zts`, `apache-mod-7.4-zts`, `apache-mod-7.3-zts`, `apache-mod-7.2-zts`, `apache-mod-7.1-zts`, `apache-mod-7.0-zts`, `php-fpm-8.1`, `php-fpm-8.0`, `php-fpm-7.4`, `php-fpm-7.3`, `php-fpm-7.2`, `php-fpm-7.1`, `php-fpm-7.0` * For `python`: `flask-poc` (default), `fastapi`, `uwsgi-poc`, `django-poc`, `python3.12` * For `ruby`: `rails70` (default), `rack`, `sinatra21`, and lot of other sinatra/rails versions diff --git a/docs/execute/dd-trace-debug.md b/docs/execute/dd-trace-debug.md new file mode 100644 index 00000000000..49701f0ef98 --- /dev/null +++ b/docs/execute/dd-trace-debug.md @@ -0,0 +1,19 @@ +End-to-end testing requires to have a setup as close as possible to what would be "real condition". It means that we try to not set any environment variaible that would change the library behavior if it's not what would be typically used by our customers (and if it's not what we want to tests). + +In consequence, DD_TRACE_DEBUG is not set. Though, it makes any debugging session hard. You can locally (or temporary in your CI) activate this by using one of those two ways : + +## `--force-dd-trace-debug` option + +By adding this option to your `./run.sh` script, you will activate debug logs in the weblog : + +```bash +./run.sh --force-dd-trace-debug +``` + +## Using `SYSTEM_TESTS_FORCE_DD_TRACE_DEBUG` en var + +By setting this env var to `true`, you'll achieve the same effect. A convenient way if you want to always have this locally, is to add it to your `.env` file. + +```bash +echo "SYSTEM_TESTS_FORCE_DD_TRACE_DEBUG=true" >> .env +``` diff --git a/docs/execute/force-execute.md b/docs/execute/force-execute.md index eeb68c35530..87a9034f845 100644 --- a/docs/execute/force-execute.md +++ b/docs/execute/force-execute.md @@ -1,11 +1,6 @@ Test items are skipped (or not) based on declarations in tests class, using manifest, or @bug/flaky/missing_feature decorators. -This fact implies an [egg-chicken issue](../edit/egg-chicken-changes.md) if you need to work on a feature. A way to handle it is to use the `-F` option : +You can force a disabled test to execute using the `-F` option, e.g. +`./run.sh MY_SCENARIO -F tests/feature.py::Test_Feature -F tests/feature.py::Test_FeatureEdgeCase` -1. in your PR, modify your CI to include the test you want to activate: - * `./run.sh MY_SCENARIO -F tests/feature.py::Test_Feature -F tests/feature.py::Test_FeatureEdgeCase` -2. iterate on your PR, merge it - -:warning: Do not forget to add a PR in system-tests repo, otherwise we may change the test, and break your CI without noticing it. - -And so time to time, removes all the `-F` in your CI. + A common use-case is if a feature covered by a test is currently in progress for your library. Once progress is complete, follow the [enable-test.md](../edit/enable-test.md) doc to enable the test in CI. diff --git a/docs/execute/requirements.md b/docs/execute/requirements.md deleted file mode 100644 index 30822bacf13..00000000000 --- a/docs/execute/requirements.md +++ /dev/null @@ -1,38 +0,0 @@ -You''ll need a bash based terminal, docker and python3.9 - -## python3.9 - -### Ubuntu - -``` -sudo add-apt-repository ppa:deadsnakes/ppa -sudo apt update -sudo apt install python3.9 python3.9-distutils python3.9-venv -curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py -python3.9 get-pip.py -./build.sh -i runner -``` - -### Windows - -TODO - -### Mac - -For Homebrew users : - -``` -brew install python@3.9 -pip3.9 install virtualenv -``` - -## Bash based terminal for Windows - -TODO - -## Docker - -TODO - - - diff --git a/docs/execute/run.md b/docs/execute/run.md index 22137e57da5..4ee2e12dddc 100644 --- a/docs/execute/run.md +++ b/docs/execute/run.md @@ -24,10 +24,10 @@ If the test contains `@scenarios.SCENARIO_NAME` such as `@scenarios.integrations ## Run only one class, or one method ```bash -./run.sh tests/test_waf.py::Test_WAFAddresses +./run.sh tests/parametric/test_waf.py::Test_WAFAddresses # and one method: -./run.sh tests/test_waf.py::Test_WAFAddresses::test_post_json_value +./run.sh tests/parametric/test_waf.py::Test_WAFAddresses::test_post_json_value ``` ## Run a scenario diff --git a/docs/execute/skip-empty-scenario.md b/docs/execute/skip-empty-scenario.md new file mode 100644 index 00000000000..7cf29e99822 --- /dev/null +++ b/docs/execute/skip-empty-scenario.md @@ -0,0 +1,3 @@ +The `--skip-empty-scenario` option will deselected all tests if the current scenario contains only tests marked as xfail or skipped (`bug`, `flaky`, `missing_feature`, `irrelevant`). + +This option can also be activated with then environment variable `SYSTEM_TESTS_SKIP_EMPTY_SCENARIO=True` \ No newline at end of file diff --git a/docs/execute/test-outcomes.md b/docs/execute/test-outcomes.md index c0e3b0e889b..f5425cf6392 100644 --- a/docs/execute/test-outcomes.md +++ b/docs/execute/test-outcomes.md @@ -2,11 +2,11 @@ Each test can be flagged with an expected outcomes, with a declaration in [manif Those declaration are interpreted by system-tests and impacts the test execution, and the outcome of the entire run : -| Declaration | Test is executed | Test actual outcome | System test output | Comment -| - | - | - | - | - -| \ | Yes | ✅ Pass | 🟢 Success | All good :sunglasses: -| Missing feature or bug | Yes | ❌ Fail | 🟢 Success | Expected failure -| Missing feature or bug | Yes | ✅ Pass | 🟠 Success | XPASS: The feature has been implemented, bug has been fixed -> easy win -| Flaky | No | N.A. | N.A. | A flaky test doesn't provide any usefull information, and thus, is not executed. -| Irrelevant | No | N.A. | N.A | There is no purpose of running such a test -| \ | Yes | ❌ Fail | 🔴 Fail | Only use case where system test fails : the test should have been ok, and is not +| Declaration | Test is executed | Test actual outcome | System test output | Comment +| - | - | - | - | - +| \ | Yes | ✅ Pass | 🟢 Success | All good :sunglasses: +| Missing feature or bug or incomplete test app | Yes | ❌ Fail | 🟢 Success | Expected failure +| Missing feature or bug or incomplete test app | Yes | ✅ Pass | 🟠 Success | XPASS: The feature has been implemented, bug has been fixed -> easy win +| Flaky | No | N.A. | N.A. | A flaky test doesn't provide any usefull information, and thus, is not executed. +| Irrelevant | No | N.A. | N.A | There is no purpose of running such a test +| \ | Yes | ❌ Fail | 🔴 Fail | Only use case where system test fails : the test should have been ok, and is not diff --git a/docs/execute/troubleshooting.md b/docs/execute/troubleshooting.md index 91c50d56a5f..c2006ea8ba0 100644 --- a/docs/execute/troubleshooting.md +++ b/docs/execute/troubleshooting.md @@ -1,15 +1,14 @@ ## `docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))` -Your docker engine is not started or not ready. start it, and wait. -It also happens when you do not allow the default socket to be used (see Advanced options in docker desktop). +Your docker engine is either not started or not ready. Start it, and wait a bit before trying again. This error also happens when you do not allow the default socket to be used (see Advanced options in docker desktop). ## On Mac/Parametric tests, fix "allow incoming internet connection" popup -The popup should disappear, don't worry +The popup should disappear, don't worry. ## Errors on build.sh -When running `build.sh`, you have this error : +When running `build.sh`, you have this error: ### `failed to solve: system_tests/weblog` @@ -17,10 +16,10 @@ When running `build.sh`, you have this error : ERROR: failed to solve: system_tests/weblog: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed ``` -It says it try to get `system_tests/weblog` image from docker hub because it does not exists loccaly. But a `docker images ls -a | grep weblog` says this image exists. You may not using the `default` docker buildx, try : +This error message says that the build script tried to pull the `system_tests/weblog` image from docker hub because it does not exist locally. However, `docker image ls -a | grep weblog` says that this image does exist locally. You may need to switch to the `default` docker buildx. Try: ```bash -docker buildx use default +docker context use default ``` ### `open /Users//.docker/buildx/current: permission denied` @@ -31,7 +30,7 @@ ERROR: open /Users//.docker/buildx/current: permission denied Build step failed after 1 attempts ``` -File permission on your `.docker` are not the good ones : +Adjust file permissions on your `.docker`: ```bash sudo chown -R $(whoami) ~/.docker @@ -39,4 +38,32 @@ sudo chown -R $(whoami) ~/.docker ## NodeJs weblog experimenting segfaults on Mac/Intel -In docker dashbaord, setting, general, untick `Use Virtualization Framework`. See this [Stack overflow thread](https://stackoverflow.com/questions/76735062/segmentation-fault-in-node-js-application-running-in-docker). \ No newline at end of file +In the docker dashboard -> settings -> general, untick `Use Virtualization Framework`. See this [Stack overflow thread](https://stackoverflow.com/questions/76735062/segmentation-fault-in-node-js-application-running-in-docker) for more information. + +## Parametric scenario: `GRPC recvmsg:Connection reset by peer` + +The GRPC interface seems to be less stable. So far, the only solution is to retry. + +## Parametric scenario: `Fail to bind port` + +Docker seems to occasionally keep a host port open, even after the container is removed. There is the wait-and-retry mechanism, but it may not be enough. So far, the only solution is to retry. + +## Install python3.12 on ubuntu + +`apt-get install python3.12 python3.12-dev python3.12-venv` + +## Unable to start postgres instance + +When executing `run.sh`, postgres can fail to start and log: + +``` +/usr/local/bin/docker-entrypoint.sh: line 177: /docker-entrypoint-initdb.d/init_db.sh: Permission denied +``` + +This may happen if your `umask` prohibits "other" access to files (for example, it is `027` on Datadog Linux laptops). To fix this, try: + +```bash +chmod 755 ./utils/build/docker/postgres-init-db.sh +``` + +Then, rebuild and rerun. diff --git a/docs/execute/xfail-strict.md b/docs/execute/xfail-strict.md new file mode 100644 index 00000000000..cfd9a09286d --- /dev/null +++ b/docs/execute/xfail-strict.md @@ -0,0 +1,12 @@ +If a test is flagged as `missing_feature` or `bug`, the test will be executed and : + +* if it fails, it will be ignored +* if it passes, a warning will be printed, with the mention XPASS, but it does not fail the entire process + +For some reason, you may want to have the process to fail if there is a `XPASS`. To achieve that, add the `-o xfail_strict=True` option to the `./run.sh` command. + +Though, you must be careful you if use this option in your CI. As system-tests are continuously updated with new tests, and by default, missing_feature are added on all languages, your CI may be broken suddendly. So it's strongly recommended to pin the system-tests version in your CI if you want to use this option. + +For this same reason, this option is **not** used in system-tests CI. + +Though, it's recommended to use this option in your release process, to guarantee that you don't have forgotten test. The page [Easy-Wins page on Feature Parity Dashbaord](https://feature-parity.us1.prod.dog/#/easy-wins) is also a convenient way to track those xpass. \ No newline at end of file diff --git a/docs/internals/end-to-end-life-cycle.md b/docs/internals/end-to-end-life-cycle.md new file mode 100644 index 00000000000..58afd757236 --- /dev/null +++ b/docs/internals/end-to-end-life-cycle.md @@ -0,0 +1,28 @@ +The majority of scenario in system tests are based on `EndToEndScenario` class, itself based on `_DockerScenario` class. One of the major constraints of those scenario is to precisely control the startup sequence, to ensure that no flakyness is induced by a service not healthy when a depending one is rely on it. + +Once the infra is ready to be tested, the test execution is divided in three sequential steps : setup, wait, then test. + +Here is the life cycle map : + +```mermaid +flowchart TD + Proxy --> Agent + C --> B + Agent --> B[[Buddies]] + Agent --> Weblog + D[Open telemetry collector] + C[[Postgres, and any other DB engine...]] --> Weblog + Weblog --> E(Infra ready to be tested):::greenText + D --> E + B --> E + E --> F[Execution of all setup methods] + F --> G[Grace period] + G --> H[Execution of all relevants test methods] + classDef greenText color:#2B2 +``` + +Two important note : + +1. each container must satisfy to an healtcheck command to be consider as started +2. depending on the scenario, some container may not be started (Buddies, DB engines, OTM collector ...) +3. on `replay` mode, only the very last step (`Execution of all relevants test methods`) is executed. diff --git a/docs/internals/flushing.md b/docs/internals/flushing.md index 78a30cb8a02..b542d6be33b 100644 --- a/docs/internals/flushing.md +++ b/docs/internals/flushing.md @@ -2,7 +2,7 @@ ## Default behavior -Before running assertions, the system-test will wait a certain amount of time (defined in [_scenarios.py](https://github.com/DataDog/system-tests/blob/9ae1dcff8ca55bcc4157781a406bbcafeb358d54/utils/_context/_scenarios.py#L424)), to wait for all remaining data to be flushed. +Before running assertions, the system-test will wait a certain amount of time (defined in [endtoend.py](https://github.com/DataDog/system-tests/blob/fe8f0cc6b7879ed448148906232fbd12925a0f7b/utils/_context/_scenarios/endtoend.py#L318)), to wait for all remaining data to be flushed. It will then stop the weblog container, and only then run all the assertions. ## Implicit flushing @@ -13,4 +13,4 @@ Before running the assertions, the system-tests will stop the weblog application It is possible to use explicit flushing instead of the default delay. To do so, implement an endpoint in your weblog `GET /flush`, that when called, will force the flushing of all library data. -You then need to add your library to the list of supported explicity flushing in: TODO LINK, and finally you can set your library delay to 0. +You then need to add your library to the list of supported explicitly flushing in [endtoend.py](https://github.com/DataDog/system-tests/blob/fe8f0cc6b7879ed448148906232fbd12925a0f7b/utils/_context/_scenarios/endtoend.py#L413), and finally you can set your library delay to 0 in [endtoend.py](https://github.com/DataDog/system-tests/blob/fe8f0cc6b7879ed448148906232fbd12925a0f7b/utils/_context/_scenarios/endtoend.py#L318). diff --git a/docs/internals/life_cycle.md b/docs/internals/life_cycle.md deleted file mode 100644 index 93f6f842041..00000000000 --- a/docs/internals/life_cycle.md +++ /dev/null @@ -1,21 +0,0 @@ -## Docker compose - -The docker compose file includes several dependancies between each services. Here is the startup diagram of all services: - -```mermaid -graph TD - runner --> agent - agent --> weblog - runner --> weblog - cassandra[(cassandra)] ----> weblog - mongo[(mongo)] ----> weblog -``` - -## Warmup - -Once the runner is started, it waits for several signals (defined in `execute_warmups` function) before starting the test session: - -1. A successful request on `agent` service -2. A successful request on `weblog` service -3. A successful communication between `weblog` and `agent` -4. A successful communication between `agent` and datadog backend diff --git a/docs/internals/parametric-life-cycle.md b/docs/internals/parametric-life-cycle.md new file mode 100644 index 00000000000..d58fdecaa05 --- /dev/null +++ b/docs/internals/parametric-life-cycle.md @@ -0,0 +1,7 @@ +Parametric scenario is a scenario that only targets libraries. It spawns, for each test, docker network, a container with the tested library behind a custom HTTP interface\*, and a container with a test agent. Those three items are removed at the end of the test. + +To keep this scenario reasonably fast, it also use `xdist` plugin, that split the test session in as many core as it exists. Here is an example with two cores : + +![Output on success](../../utils/assets/parametric_infra.png?raw=true) + +Note : [previously a gRPC interface](https://github.com/DataDog/system-tests/issues/1930) diff --git a/docs/internals/test-flow.md b/docs/internals/test-flow.md new file mode 100644 index 00000000000..0ae816dfd61 --- /dev/null +++ b/docs/internals/test-flow.md @@ -0,0 +1,24 @@ +Here is the execution flow of tests + +## end-to-end scenario + +### Normal mode + +1. The infra is spawned +2. All tests are collected, tests that are not in the executed scenario are removed +3. for each tests, if the test is a method class, and a setup method exists in this class (test is named `test_XXX`, setup method name must be `setup_XXX`), the setup method is executed. +4. Every data generated by the setup method is stored (actually, only requests made on the weblog, but soon all of them) +5. the infra is shut down +6. all the test method are executed + +### Replay mode + +1. All tests are collected, tests that are not in the executed scenario are removed +2. data generated by the setup method is recreated +6. all the test method are executed + +## Parametric scenario + +WIP + + diff --git a/docs/lib-injection/docker_ssi_lib_injections_folders.png b/docs/lib-injection/docker_ssi_lib_injections_folders.png new file mode 100644 index 00000000000..7deeaaa6e19 Binary files /dev/null and b/docs/lib-injection/docker_ssi_lib_injections_folders.png differ diff --git a/docs/lib-injection/k8s_djm.png b/docs/lib-injection/k8s_djm.png new file mode 100644 index 00000000000..cd8d68804ae Binary files /dev/null and b/docs/lib-injection/k8s_djm.png differ diff --git a/docs/lib-injection/k8s_lib_injections_folders.png b/docs/lib-injection/k8s_lib_injections_folders.png index d5a8f1d6827..0ce60ac4eff 100644 Binary files a/docs/lib-injection/k8s_lib_injections_folders.png and b/docs/lib-injection/k8s_lib_injections_folders.png differ diff --git a/docs/lib-injection/k8s_lib_injections_log_folders.png b/docs/lib-injection/k8s_lib_injections_log_folders.png index 959be9c06bf..698b40f9bf4 100644 Binary files a/docs/lib-injection/k8s_lib_injections_log_folders.png and b/docs/lib-injection/k8s_lib_injections_log_folders.png differ diff --git a/docs/lib-injection/lib-injection-tests.png b/docs/lib-injection/lib-injection-tests.png index 2c1d6b639da..09351db3a89 100644 Binary files a/docs/lib-injection/lib-injection-tests.png and b/docs/lib-injection/lib-injection-tests.png differ diff --git a/docs/lib-injection/onboarding_overview.png b/docs/lib-injection/onboarding_overview.png new file mode 100644 index 00000000000..f51914da0c2 Binary files /dev/null and b/docs/lib-injection/onboarding_overview.png differ diff --git a/docs/lib-injection/ssi_lib_injections_folders.png b/docs/lib-injection/ssi_lib_injections_folders.png new file mode 100644 index 00000000000..b81c97cba9d Binary files /dev/null and b/docs/lib-injection/ssi_lib_injections_folders.png differ diff --git a/docs/lib-injection/ssi_lib_injections_log_folders.png b/docs/lib-injection/ssi_lib_injections_log_folders.png new file mode 100644 index 00000000000..1ddfa216fdc Binary files /dev/null and b/docs/lib-injection/ssi_lib_injections_log_folders.png differ diff --git a/docs/scenarios/IPv6.md b/docs/scenarios/IPv6.md new file mode 100644 index 00000000000..d9851dd74af --- /dev/null +++ b/docs/scenarios/IPv6.md @@ -0,0 +1,5 @@ +The `IPV6` scenario setup an IPv6 docker network and use an IPv6 address as DD_AGENT_HOST to verify that the library is able to communicate to the agent using an IPv6 address. It does not use a proxy between the lib and the agent to not interfer at any point here, so all assertions must be done on the outgoing traffic from the agent. + +Please note that it requires the docker daemon to supports IPv6. It should be ok on Linux CI and Mac OS, but has not be tested on Windows. + +A user has seen his network function altered after running it on a linux latptop (to be investigated). If it happen, `docker network prune` may sole the issue. diff --git a/docs/scenarios/README.md b/docs/scenarios/README.md index 5c96fc2cf3c..4a5d1b464f6 100644 --- a/docs/scenarios/README.md +++ b/docs/scenarios/README.md @@ -34,13 +34,17 @@ class Test_Something: ## Scenarios +System-tests contains various testing scenarios; the two most commonly used are called "End-To-End" and "Parametric." + ### End to end scenarios -Based on class `EndToEndScenario`, they spwan a weblog (HTTP app shipping a tracer), an agent, a proxy between tracer-agent-backend, and run a set of high level functionnal tests. The `DEFAULT` scenario is the main scenario of system tests, and is in this family. +Based on class `EndToEndScenario`, they spwan a "weblog" HTTP server designed to mimick customer applications with automatic instrumentation, a "test-agent" to mimick the Datadog Agent, and communication with the Datadog backend via a proxy. The `DEFAULT` scenario is the main scenario of system tests, and is in this family. + +End-To-End scenarios are good for testing real-world scenarios — they support the full lifecycle of a trace (hence the name, "End-To-End"). Use End-To-End scenarios to test tracing integrations, security products, profiling, dynamic instrumentation, and more. When in doubt, use end-to-end. ### Parametric scenario -Parametric scenario build and spawn a tracer with a simple GRPC interface. It's not really unit tests (still black-box testing), neither functionnal tests (only tracers are tested), they are convenient to tests different parameter set for tracers. More detailled documentation can be found [here](https://github.com/DataDog/system-tests/blob/main/docs/scenarios/parametric.md). +Parametric scenarios are designed to validate tracer and span interfaces. They are more lightweight and support testing features with many input parameters. They should be used to test operations such as creating spans, setting tags, setting links, injecting/extracting http headers, getting tracer configurations, etc. You can find dedicated parametric instructions in the [parametric.md](https://github.com/DataDog/system-tests/blob/main/docs/scenarios/parametric.md). ### Auto-Inject/OnBoarding scenarios diff --git a/docs/scenarios/docker_ssi.md b/docs/scenarios/docker_ssi.md new file mode 100644 index 00000000000..57edb722a12 --- /dev/null +++ b/docs/scenarios/docker_ssi.md @@ -0,0 +1,401 @@ +1. [Overall](#Overall) +2. [Run the tests](#Run-the-tests) + * [Prerequisites](#Prerequisites) + - [System-tests requirements](#System-tests-requirements) + * [Run the scenario](#run-the-scenario) +3. [How to develop tests](#How-to-develop-a-test-case) + * [Folders and Files structure](#Folders-and-Files-structure) + * [Docker SSI definitions](#Docker-SSI-definitions) + * [Create a new weblog](#Create-a-new-weblog) + - [Create a new weblog using a prebuilt docker image](#Create-a-new-weblog-using-a-prebuilt-docker-image) + - [Create a new weblog deployable on different containers or operating systems](#Create-a-new-weblog-deployable-on-different-containers-or-operating-systems) + * [Create a new test case](#Create-a-new-test-case) + +# Overall + +The Docker SSI tests are an easy and fast tests to check the SSI instrumentation. +The Docker SSI tests don't pretend to reemplace the current AWS tests, there only try to complement them, providing a quick checks and verification for some features included in the SSI. + +The main differences between the AWS/Onboarding tests and the Docker SSI tests are: + +* In Docker SSI, the SSI is installed inside a docker container, instead of using virtual machines. +* The AWS/Onboarding tests represent better a real customer scenarios, but Docker SSI it doesn't. +* Docker SSI relies on APM Test Agent, instead of rely on the backend. + +The main Docker SSI properties are: + +* Install the SSI host injection on the docker container that runs the weblog application. +* Uses a APM Test Agent to make the assertions. +* The weblog applications are containerized applications. +* The weblog application container is built by the system-tests scenarios in separate steps. +* The base image of the weblog application container should be parametrizable (it will detailed in the next sections) + +The Docker SSI are good for: + +* Test the instrumentation agains different runtime versions. +* Test the guardrail features (unsupported versions of the language). +* Test the service naming features on SSI. +* Test the crash tracking features. +* Test other features like profiling, asm... + +# Run the tests + +## Prerequisites + +There are not special requirements to run the Docker SSI tests, you only need the docker engine and have the access to GHCR. + +### System-tests requirements + +All system-tests assertions and utilities are based on python and pytests. You need to prepare this environment before run the tests: + +- Python and pytests environment as described: [configure python and pytests for system-tests](../../README.md#requirements). +- Ensure that requirements.txt is loaded (you can run "`./build.sh -i runner`") + +## Run the scenario + +There is only one scenario declared: "`DOCKER_SSI`". But this unique scenario can run agains multiple variants of weblogs, conteinerized OS and architectures and therefore the matrix combinations might be very big. + +To help us to run a concrete case of the matrix variants, there are two scripts to be executed locally: + +* `utils/build/ssi/build_local_manual.sh`: Runs the Docker SSI scenario using the arguments: library, weblog, docker base image, architecture and installable runtime. To run this command you need to know the correct combination of these arguments. +* `utils/build/ssi/build_local_wizard.sh`: Interactive shell wizard that allow you to execute the Docker SSI scenario with the correct combination of arguments. + +Here is the command line and the mandatory parameters: + +```bash + ./run.sh DOCKER_SSI --ssi-weblog "$weblog" --ssi-library "$TEST_LIBRARY" --ssi-base-image "$base_image" --ssi-arch "$arch" --ssi-installable-runtime "$installable_runtime" + +``` + +The easy way to execute this scenario is to use the wizard script. For example: + +```bash +(venv) system-tests % utils/build/ssi/build_local_wizard.sh +Welcome to the SSI Wizard! +Please select the library you want to test: +1) dotnet +2) java +3) nodejs +4) php +5) python +#? 2 +You selected: java +Please select the weblog you want to use: +1) java7-app 3) jetty-app 5) websphere-app +2) jboss-app 4) tomcat-app +#? 3 +You selected: jetty-app +Please select the base image you want to use: +1) almalinux:8.10 3) oraclelinux:8.10 5) ubuntu:16.04 +2) almalinux:9.4 4) oraclelinux:9 6) ubuntu:22.04 +#? 6 +You selected: ubuntu:22.04 +Please select the architecture you want to use: +1) linux/amd64 +2) linux/arm64 +#? 2 +You selected: linux/arm64 +Please select the installable runtime you want to use: +1) 11.0.24-zulu +2) 17.0.12-zulu +3) 21.0.4-zulu +4) 22.0.2-zulu +#? 3 +You selected: 21.0.4-zulu +Enter any extra arguments (or leave blank): +Executing: ./run.sh DOCKER_SSI --ssi-weblog jetty-app --ssi-library java --ssi-base-image ubuntu:22.04 --ssi-arch linux/arm64 --ssi-installable-runtime 21.0.4-zulu +``` + +# How to develop tests + +## Folders and Files structure + +To develop a new test case in the Docker SSI Library injection tests, you need to know about the project folder structure. +The following picture shows the main directories for the Docker SSI tests: + +![Folder structure](../lib-injection/docker_ssi_lib_injections_folders.png "Folder structure") + +* **tests/docker_ssi:** All tests cases are stored on this folder. +* **utils/_context/scenarios/**: In this folder you can find the Docker SSI Lib injection scenario definition. +* **utils/build/ssi/base/:** The base templates for the Docker SSI images, and the base utilities used to build the images, for example the language runtime installers. +* **utils/build/ssi/[lang]/:** The weblog applications docker definitios. +* **utils/build/ssi/build_local_manual.sh:** The helper script to run the Docker SSI scenarios. +* **utils/build/ssi/build_local_wizard.sh:** The wizard script to run the Docker SSI scenarios. +* **utils/docker_ssi:** The core implementation of this test framework. + +## Docker SSI definitions + +The key of the matrix of OSs (docker base image), architectures, language versions and weblogs resides on the file: `utils/docker_ssi/docker_ssi_definitions.py`. This file is the glue for all the components of this large matrix. + +The first component is the Supported Images definition: + +```python +class SupportedImages: + """All supported images""" + + def __init__(self) -> None: + # Try to set the same name as utils/_context/virtual_machines.py + self.UBUNTU_22_AMD64 = DockerImage("Ubuntu_22", "ubuntu:22.04", LINUX_AMD64) + self.UBUNTU_22_ARM64 = DockerImage("Ubuntu_22", "ubuntu:22.04", LINUX_ARM64) + self.UBUNTU_16_AMD64 = DockerImage("Ubuntu_16", "ubuntu:16.04", LINUX_AMD64) + self.UBUNTU_16_ARM64 = DockerImage("Ubuntu_16", "ubuntu:16.04", LINUX_ARM64) + self.CENTOS_7_AMD64 = DockerImage("CentOS_7", "centos:7", LINUX_AMD64) +``` + +Other component to be defined is the installable runtime versions of the languages that are supported: + +```python +class JavaRuntimeInstallableVersions: + """Java runtime versions that can be installed automatically""" + + JAVA_22 = RuntimeInstallableVersion("JAVA_22", "22.0.2-zulu") + JAVA_21 = RuntimeInstallableVersion("JAVA_21", "21.0.4-zulu") + JAVA_17 = RuntimeInstallableVersion("JAVA_17", "17.0.12-zulu") + JAVA_11 = RuntimeInstallableVersion("JAVA_11", "11.0.24-zulu") + +class PHPRuntimeInstallableVersions: + """PHP runtime versions that can be installed automatically""" + + PHP56 = RuntimeInstallableVersion("PHP56", "5.6") + PHP70 = RuntimeInstallableVersion("PHP70", "7.0") + PHP71 = RuntimeInstallableVersion("PHP71", "7.1") + +``` + +Finally, there is a place to define the weblogs and specify on which OSs/docker base images can be deployed and whether it supports the installation of different language versions. + +```python +JS_APP = WeblogDescriptor( + "js-app", + "nodejs", + [ + SupportedImages().UBUNTU_22_AMD64.with_allowed_runtime_versions( + JSRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().UBUNTU_22_ARM64.with_allowed_runtime_versions( + JSRuntimeInstallableVersions.get_all_versions() + ), + ], +) +``` + +Might be your weblog only supports one base image and it's required a runtime version to be installed, for example: + +```python +TOMCAT_APP = WeblogDescriptor("tomcat-app", "java", [SupportedImages().TOMCAT_9_ARM64]) +JAVA7_APP = WeblogDescriptor("java7-app", "java", [SupportedImages().UBUNTU_22_ARM64]) +WEBSPHERE_APP = WeblogDescriptor("websphere-app", "java", [SupportedImages().WEBSPHERE_AMD64]) +JBOSS_APP = WeblogDescriptor("jboss-app", "java", [SupportedImages().JBOSS_AMD64]) +``` + +## Create a new weblog + +We can differentiate between two types of applications: + +- Applications that come already prepared/wrapped with a base image. For example, tomcat or jboss. +- "Normal” applications that we encapsulate in a docker container and that in theory could be executed in more than one base image. For example, my HelloWorld application could run on Ubuntu22, Debian 12, RedHat.... images. + +The two previous points, will be better understood by following examplesThe previous. + +### Create a new weblog using a prebuilt docker image + +For example, the Tomcat Java Web Server is distributed by a prebuilt docker images. If we want to test the tomcat 9, but we don't need to test Tomcat 9 installed on different Operating Systems, we could use the tomcat prebuilt images. + +If we want to test the tomcat 9 image deploying a web application we'd do this: + +```yaml +#Build the web app +FROM maven:3.5.3-jdk-8-alpine as build +WORKDIR /app +COPY lib-injection/build/docker/java/enterprise/ ./ +RUN mvn clean package + +#Deploy/Run the built app on a tomcat 9 +FROM tomcat:9 +COPY --from=build app/payment-service/target/payment-service*.war /usr/local/tomcat/webapps/ +``` + +We can convert this standard image into "Docker SSI" image. We only need to parametrize the "From" clausule, and store the dockerfile as `utils/build/ssi/java/tomcat-app.Dockerfile`: + +```yaml +ARG BASE_IMAGE + +FROM maven:3.5.3-jdk-8-alpine as build +WORKDIR /app +COPY lib-injection/build/docker/java/enterprise/ ./ +RUN mvn clean package + +FROM ${BASE_IMAGE} +COPY --from=build app/payment-service/target/payment-service*.war /usr/local/tomcat/webapps/ +#This is the endpoint to be used by the tests to make a request to the weblog. If your app it's listenning on "http://localhost:18080" you don't need to use the "WEBLOG_URL" +ENV WEBLOG_URL=http://localhost:8080/payment-service/ +ENV DD_INSTRUMENT_SERVICE_WITH_APM=true +``` + +As final step, we should register the new weblog in the docker ssi definitions file (`utils/docker_ssi/docker_ssi_definitions.py`): + +```python +class SupportedImages: + """All supported images""" + + def __init__(self) -> None: + self.TOMCAT_9_AMD64 = DockerImage("Tomcat_9", "tomcat:9", LINUX_AMD64) + self.TOMCAT_9_ARM64 = DockerImage("Tomcat_9", "tomcat:9", LINUX_ARM64) +... +TOMCAT_APP = WeblogDescriptor("tomcat-app", "java", [SupportedImages().TOMCAT_9_ARM64, SupportedImages().TOMCAT_9_AMD64]) +... +# HERE ADD YOUR WEBLOG DEFINITION TO THE LIST +ALL_WEBLOGS = [ + ..., + TOMCAT_APP, + ... +] + +``` + +--- + +**NOTE:** + +When system-tests builds the docker images is going to install the SSI software inside of the container. + +--- + +If we want to run the "DOCKER_SSI" test cases for this new weblog: + +```bash +./run.sh DOCKER_SSI --ssi-weblog tomcat-app --ssi-library java --ssi-base-image tomcat:9 --ssi-arch linux/arm64 +``` + +### Create a new weblog deployable on different containers or operating systems + +We will use these types of weblogs to run an application agains different operating systems and distincs language runtime versions. + +For example, we can define the PHP application that run the app into different OS and PHP runtime versions (`utils/build/ssi/php/php-app.Dockerfile`): + +```yaml +ARG BASE_IMAGE + +FROM ${BASE_IMAGE} +WORKDIR /app + +RUN printf " index.php + +# Without the sleep, the docker network has issues +CMD ["sh", "-c", "sleep 2; php -S 0.0.0.0:18080"] +``` + +As final step, we should register the new weblog in the docker ssi definitions file (`utils/docker_ssi/docker_ssi_definitions.py`): + +```python +class SupportedImages: + """All supported images""" + + def __init__(self) -> None: + # Try to set the same name as utils/_context/virtual_machines.py + self.UBUNTU_22_AMD64 = DockerImage("Ubuntu_22", "ubuntu:22.04", LINUX_AMD64) + self.UBUNTU_24_ARM64 = DockerImage("Ubuntu_24", "ubuntu:24.04", LINUX_ARM64) + +class PHPRuntimeInstallableVersions: + """PHP runtime versions that can be installed automatically""" + + PHP56 = RuntimeInstallableVersion("PHP56", "5.6") # Not supported (EOL runtime) + PHP70 = RuntimeInstallableVersion("PHP70", "7.0") + PHP71 = RuntimeInstallableVersion("PHP71", "7.1") + PHP72 = RuntimeInstallableVersion("PHP72", "7.2") + PHP73 = RuntimeInstallableVersion("PHP73", "7.3") + PHP74 = RuntimeInstallableVersion("PHP74", "7.4") + PHP80 = RuntimeInstallableVersion("PHP80", "8.0") + PHP81 = RuntimeInstallableVersion("PHP81", "8.1") + PHP82 = RuntimeInstallableVersion("PHP82", "8.2") + PHP83 = RuntimeInstallableVersion("PHP83", "8.3") + +... + +PHP_APP = WeblogDescriptor( + "php-app", + "php", + [ + SupportedImages().UBUNTU_22_AMD64.with_allowed_runtime_versions( + PHPRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().UBUNTU_24_ARM64.with_allowed_runtime_versions( + PHPRuntimeInstallableVersions.get_all_versions() + ), + ], +) + +... +# HERE ADD YOUR WEBLOG DEFINITION TO THE LIST +ALL_WEBLOGS = [ + ..., + PHP_APP, + ... +] +``` + +--- + +**NOTE:** + +When system-tests builds the docker images is going to install the SSI software inside of the container and the required runtime version. + +--- + +If we want to run a "DOCKER_SSI" test case for this new weblog: + +```bash +./run.sh DOCKER_SSI --ssi-weblog php-app --ssi-library php --ssi-base-image ubuntu:22.04 --ssi-arch linux/amd64 --ssi-installable-runtime PHP70 +``` + +## Create a new test case + +The creation of test methods for the “Docker SSI” scenarios does not require anything special, we will do it as it is done for the rest of the system-tests scenarios. +We can make request to the deployed weblog and make assertiong throught the "test agent" interface: + +```python +@scenarios.docker_ssi +class TestDockerSSIFeatures: + """Test the ssi in a simulated host injection environment (docker container + test agent) + We test that the injection is performed and traces and telemetry are generated. + If the language version is not supported, we only check that we don't break the app and telemetry is generated.""" + + + def setup_install_supported_runtime(self): + + parsed_url = urlparse(context.scenario.weblog_url) + logger.info(f"Setting up Docker SSI installation WEBLOG_URL {context.scenario.weblog_url}") + self.r = weblog.request( + "GET", parsed_url.path, domain=parsed_url.hostname, port=parsed_url.port + ) + logger.info(f"Setup Docker SSI installation {TestDockerSSIFeatures._r}") + + + def setup_install_supported_runtime(self): + self._setup_all() + + @features.ssi_guardrails + def test_install_supported_runtime(self): + logger.info(f"Testing Docker SSI installation on supported lang runtime: {context.scenario.library.library}") + assert self.r.status_code == 200, f"Failed to get response from {context.scenario.weblog_url}" + + # If the language version is supported there are traces related with the request + traces_for_request = interfaces.test_agent.get_traces(request=self.r) + assert traces_for_request, f"No traces found for request {get_rid_from_request(self.r)}" + assert "runtime-id" in traces_for_request["meta"], "No runtime-id found in traces" + + # There is telemetry data related with the runtime-id + telemetry_data = interfaces.test_agent.get_telemetry_for_runtime(traces_for_request["meta"]["runtime-id"]) + assert telemetry_data, "No telemetry data found" + +``` + +You could use the system-tests decorator to skip the tests or mark them as bug. For example: + +```python + @bug(condition=context.library == "python", reason="INPLAT-11") + @irrelevant(context.library == "java" and context.installed_language_runtime < "1.8.0_0") + @irrelevant(context.library == "php" and context.installed_language_runtime < "7.0") + @irrelevant(context.library == "nodejs" and context.installed_language_runtime < "17.0") + def test_install_supported_runtime(self): +``` diff --git a/docs/scenarios/external_processing.md b/docs/scenarios/external_processing.md new file mode 100644 index 00000000000..2646668dbdd --- /dev/null +++ b/docs/scenarios/external_processing.md @@ -0,0 +1,17 @@ +```mermaid +flowchart LR +%% Nodes + A("Test runner") + B("Envoy") + C("External Processing") + D("HTTP app") + E("Proxy") + F("Agent") + G("Backend") + +%% Edge connections between nodes + A --> B --> D + B --> C --> B + C --> E --> F --> G + %% D -- Mermaid js --> I --> J +``` \ No newline at end of file diff --git a/docs/scenarios/k8s_lib_injection.md b/docs/scenarios/k8s_lib_injection.md index 9d292926b76..45ff95a514e 100644 --- a/docs/scenarios/k8s_lib_injection.md +++ b/docs/scenarios/k8s_lib_injection.md @@ -1,6 +1,24 @@ -# lib-injection feature - -## What is the lib-injection feature? +# Testing K8s library injection feature + +1. [Overall](#Overall) + * [What is the library injection feature?](#What-is-the-k8s-library-injection-feature?) + * [What’s the Datadog Cluster Agent and why?](#What’s-the-Datadog-Cluster-Agent-and-why?) +2. [K8s tested components](#K8s-tested-components) +3. [Run the tests](#K8s-tested-components) + * [Run K8s library image validation](#Run-K8s-library-image-validation) + * [Run K8s library injection tests](#Run-K8s-library-injection-tests) + - [Prerequisites](#Prerequisites) + - [Configure tested components versions](#Configure-tested-components-versions) + - [Execute a test scenario](#Execute-a-test-scenario) +4. [How to develop a test case](#How-to-develop-a-test-case) + * [Folders and Files structure](#Folders-and-Files-structure) + * [Implement a new test case](#Implement-a-new-test-case) +5. [How to debug your kubernetes environment and tests results](#How-to-debug-your-kubernetes-environment-and-tests-results) +6. [How to debug your kubernetes environment at runtime](#How-to-debug-your-kubernetes-environment-at-runtime) + +## Overall + +### What is the k8s library injection feature? The lib-injection project is a feature to allow injection of the Datadog library into a customer's application container without requiring them to modify their @@ -13,17 +31,13 @@ APM libraries. Currently, there are two different ways to have the Datadog library injected into the application container: -1) Manually via Kubernetes annotations: - * Using Datadog Admission Controller: [Injecting Libraries Kubernetes](https://docs.datadoghq.com/tracing/trace_collection/admission_controller/). - * Adding library injection specific annotations (without Datadog Admission Controller): [Application Instrumentation](https://docs.datadoghq.com/tracing/trace_collection/), [Add the Datadog Tracing Library](https://docs.datadoghq.com/tracing/trace_collection/) -2) Automatically with Remote Config via the Datadog UI. - -`Remote config is tricky to test in a isolated environment. K8s Lib Injection tests use Kubernetes ConfigMap to emulate the configuration applied through Datadog Remote Config utility. Kubernetes ConfigMaps allows the injection of configuration into an application. ConfigMap can be injected as environment variables or mounted files.` +1) **Manually via Kubernetes annotations**: + * Using Datadog Admission Controller: [Injecting Libraries Kubernetes](https://docs.datadoghq.com/tracing/trace_collection/admission_controller/). + * Adding library injection specific annotations (without Datadog Admission Controller): [Application Instrumentation](https://docs.datadoghq.com/tracing/trace_collection/), [Add the Datadog Tracing Library](https://docs.datadoghq.com/tracing/trace_collection/) +2) **Automatically with Remote Config via the Datadog UI.** -[Read more about the Kubernetes ConfigMaps](https://kubernetes.io/docs/concepts/configuration/configmap/) - -## What’s the Datadog Cluster Agent and why? +### What’s the Datadog Cluster Agent and why? The Cluster Agent is a different binary (vs the regular Agent), written in Go in the same DataDog/datadog-agent repo and is installed as a Deployment in Kubernetes, not a DaemonSet. It’s an essential component for cluster-level monitoring. @@ -34,89 +48,85 @@ Kubernetes admission controllers are plugins that govern and enforce how the clu The Datadog admission controller is a component of the Datadog Cluster Agent. It leverages the Kubernetes mutatingwebhookconfigurations.admissionregistration.k8s.io API. -# Validating lib-injection images +## K8s tested components + +K8s Library injection testing is part of the "system-tests" test suite. + +As a final purpose we want to check the correct operation of all Datadog components involved in the auto instrumentation of the applications deployed in a kubernetes cluster. + +In the auto-instrumentation proccess there are several software components involved: + +- **Cluster agent:** Software component, written in Go, that resides on the DataDog/datadog-agent repository and is installed as a Deployment in Kubernetes. +- **Injector image:** Directly involved in auto-instrumentation. Resides on Datadog/auto_inject repository. +- **Library image (lib-init):** Contains the tracer library to be injected in the pods. + +These test components are also involved through the testing process: + +- **System-tests runner:** The core of the system-tests is the reponsible for orchestrate the tests execution and manage the tests results. +- **Dev test agent:** The APM Test Agent container help us to perform the validations ([APM Test Agent](https://github.com/DataDog/dd-apm-test-agent)). +- **Sample app/weblog:** Containerized sample application implemented on Java, Nodejs, dotNet, Ruby or Python. + +The following image represents, in general terms, the necessary and dependent architecture to be able to run the K8s library injection tests: + +![Architecture overview](../lib-injection/lib-injection-tests.png "Architecture overview") + +## Run the tests + +### Run K8s library image validation We have created some simple tests, able to auto inject the tracer library in any application running in a docker container. -On the test application container (weblog) the lib-init image will be attached as a docker volume and the environment variables, necessary for auto injection, will be attached. -The only requirement of the weblog application is that it is listening on port 18080. -The weblog will be deployed next to the APM Test Agent container, which will help us to perform the validations ([APM Test Agent](https://github.com/DataDog/dd-apm-test-agent)). +On the test application container (weblog), the lib-init image will be added as a docker volume and the environment variables, necessary for auto injection, will be attached. +The weblog application only requires to be listening on port 18080. +The weblog will be deployed together with the APM Test Agent container, which will help us to perform the validations ([APM Test Agent](https://github.com/DataDog/dd-apm-test-agent)). Now we can test the auto instrumentation on any image in two simple steps: -1. Build your app image and tag locally as "weblog-injection:latest". : +1. **Build your app image and tag locally as "weblog-injection:latest"** : + ``` docker build -t weblog-injection:latest .``` - b. You could use the existing weblog apps under _lib-injection/build/docker_ folder. Use the existing script to build them: + + You could use the existing weblog apps under __lib-injection/build/docker__ folder. Use the existing script to build them: + ``` lib-injection/build/build_lib_injection_weblog.sh -w [existing weblog] -l [java,nodejs,dotnet,ruby,python] ``` -2. Run the scenario that checks if weblog app is auto instrumented and sending traces to the _Dev Test Agent_: +ie: +``` +lib-injection/build/build_lib_injection_weblog.sh -w dd-lib-dotnet-init-test-app -l dotnet +``` + +2. **Run the scenario that checks if weblog app is auto instrumented and sending traces to the _Dev Test Agent_**: ``` TEST_LIBRARY=dotnet LIB_INIT_IMAGE=ghcr.io/datadog/dd-trace-dotnet/dd-lib-dotnet-init:latest_snapshot ./run.sh LIB_INJECTION_VALIDATION ``` -You can also validate weblog applications that the language version is not supported by the tracer. The scenario will check that the app is running although the app is not instrumented: +#### Validating lib-injection images under not supported language runtime version + +You can also validate weblog applications implemented with a language version that is not supported by the tracer. The scenario will check that the app is running although the app is not instrumented: ``` lib-injection/build/build_lib_injection_weblog.sh -w jdk7-app -l java TEST_LIBRARY=java LIB_INIT_IMAGE=ghcr.io/datadog/dd-trace-java/dd-lib-java-init:latest_snapshot ./run.sh LIB_INJECTION_VALIDATION_UNSUPPORTED_LANG ``` - - -# K8s lib-injection feature testing - -Lib injection testing is part of the "system-tests" test suite. - -To test lib-injection/autoinstrumentation feature, we run a Kubernetes cluster with the Datadog Cluster Agent and we check that the instrumentation runs smoothly using different sample applications (weblog) in different languages (currently Java, Python, Node, DotNet and Ruby). - -The following image represents, in general terms, the necessary and dependent architecture to be able to run lib-injection tests: - -![Architecture overview](../lib-injection/lib-injection-tests.png "Architecture overview") - -## Kubernetes management to automate deployments - -In order to build a simple and automated integration test suite, the "K8s Lib Injection" tests are based on Kubernetes Python Client. -[Read more about Kubernetes Python Client](https://github.com/kubernetes-client/python) - -## Folders and Files structure - -The following picture shows the main directories for the k8s lib injection tests: - -![Folder structure](../lib-injection/k8s_lib_injections_folders.png "Folder structure") - -* **lib-injection/build/docker:** This folder contains the sample applications with the source code and scripts that allow us to build and push docker weblog images. -* **tests/k8s_lib_injection:** All tests cases are stored on this folder. Conftests.py file manages the kubernetes cluster lifecycle. -* **utils/k8s_lib_injection:** Here we can find the main utilities for the control and deployment of the components to be tested. For example: - * **k8s_kind_cluster.py:** Tools for creating and destroying the Kubernetes cluster. - * **k8s_datadog_cluster_agent.py:** Utils for: - - Deploy Datadog Cluster Agent - - Deploy Datadog Admission Controller - - Apply Kubernetes ConfigMap - - Extract Datadog Components debug information. - * **k8s_weblog.py:** Manages the weblog application lifecycle. - - Deploy weblog as pod configured to perform library injection manually/without the Datadog admission controller. - - Deploy weblog as pod configured to automatically perform the library injection using the Datadog admission controler. - - Deploy weblog as Kubernetes deployment and prepare the library injection using Kubernetes ConfigMaps and Datadog Admission Controller. - - Extract weblog debug information. - * **k8s_command_utils.py:** Command line utils to lauch the Helm Chart commands and others shell commands. - -# Run the K8s Lib Injection tests in your Local +### Run K8s library injection tests These tests can run locally easily. You only have to install the environment and configure it as follow sections detail. -## Prerequisites: +#### Prerequisites: - Docker environment - Kubernetes environment -- Configure the tests (Configure the container images references) -### Docker enviroment +##### Docker enviroment -You should install the docker desktop on your computer and **be loged into a personal Docker Hub account** +You should install the docker desktop on your laptop. +You need to access to GHCR. +Usually you only need to access to GHCR to pull the images, but you can also push your custom images to your Docker Hub account. To do that you need login to Docker Hub account: ```cat ~/my_password.txt | docker login --username my_personal_user --password-stdin ``` -### Kubernetes environment +##### Kubernetes environment You should install the kind and Helm Chart tool. Kind is a tool for running local Kubernetes clusters using Docker container. @@ -159,53 +169,148 @@ chmod 700 get_helm.sh ./get_helm.sh ``` -### Environment variables +#### Configure tested components versions -The next step is define the environment variables. This is an example of env vars configuration for Java: +All the software components to be tested are configured using environment variables. This is an example of env vars configuration for Java: ```sh export TEST_LIBRARY=java export WEBLOG_VARIANT=dd-lib-java-init-test-app #Which variant do we want to use? -export LIBRARY_INJECTION_TEST_APP_IMAGE=docker.io/MY_DOCKERHUB_USERNAME/dd-lib-java-init-test-app:local #Use your docker hub account as registry +export LIBRARY_INJECTION_TEST_APP_IMAGE=ghcr.io/datadog/system-tests/dd-lib-java-init-test-app:latest #weblog variant in the registry export LIB_INIT_IMAGE=gcr.io/datadoghq/dd-lib-java-init:latest # What is the lib init image that we want to test? +export CLUSTER_AGENT_VERSION=7.56.2 +export INJECTOR_IMAGE=TODO ``` +--- +**NOTE: Injector image** -## Build and Push weblog image +Currently the tests do not allow selection of the injector image. The image used will be the one pointed by the cluster agent by default. -You need to build and push weblog application to docker registry. You can use this script: +--- -```sh - lib-injection/build/build_lib_injection_weblog.sh -w $WEBLOG_VARIANT -l $TEST_LIBRARY --push-tag $LIBRARY_INJECTION_TEST_APP_IMAGE -``` -## Build and Push init image +##### Weblog image + +The images of sample applications are automatically uploaded to the GHCR registry by the CI. -If you want to test the latest dd-lib-LANG-init image, you can skip this step. -If you want to test your own dd-lib-LANG-init image, you can build by yourself from source code or you can use a existing one: +But in case you want to build your own custom version of the application, you can do the following (the weblog images must be allwasys on a docker registry): ```sh -export LIB_INIT_IMAGE=docker.io/MY_DOCKERHUB_USERNAME/dd-lib-java-init:local -docker pull ghcr.io/datadog/dd-trace-java/dd-lib-java-init:latest_snapshot -docker tag ghcr.io/datadog/dd-trace-java/dd-lib-java-init:latest_snapshot $LIB_INIT_IMAGE -docker push $LIB_INIT_IMAGE + export LIBRARY_INJECTION_TEST_APP_IMAGE=ghcr.io/datadog/system-tests/dd-lib-java-init-test-app:my_custom_tag #weblog variant in the registry + lib-injection/build/build_lib_injection_weblog.sh -w $WEBLOG_VARIANT -l $TEST_LIBRARY --push-tag $LIBRARY_INJECTION_TEST_APP_IMAGE ``` -## Run the tests - -These K8s Lib Injection tests are fully integrated into system-tests life cycle. If we followed the previous steps, we only have to execute this command: +or if you don't have the permission to push the image to GHCR, you can use your docker hub account (after loging into it): ```sh - ./run.sh K8S_LIBRARY_INJECTION_FULL + export LIBRARY_INJECTION_TEST_APP_IMAGE=registry.hub.docker.com//dd-lib-java-init:my_custom_tag #weblog variant in the registry + lib-injection/build/build_lib_injection_weblog.sh -w $WEBLOG_VARIANT -l $TEST_LIBRARY --push-tag $LIBRARY_INJECTION_TEST_APP_IMAGE ``` -A minimum test scenario is also included. You can run it: +The sample applications currently available in GHCR are: + +| LANG | WEBLOG IMAGE | +|---|---| +| Java | ghcr.io/datadog/system-tests/dd-lib-java-init-test-app:latest | +| Java | ghcr.io/datadog/system-tests/dd-djm-spark-test-app:latest | +| DotNet | ghcr.io/datadog/system-tests/dd-lib-dotnet-init-test-app:latest | +| Nodejs | ghcr.io/datadog/system-tests/sample-app:latest | +| Python | ghcr.io/datadog/system-tests/dd-lib-python-init-test-django:latest | +| Python | ghcr.io/datadog/system-tests/dd-lib-python-init-test-django-gunicorn:latest | +| Python | ghcr.io/datadog/system-tests/dd-lib-python-init-test-django-gunicorn-alpine:latest | +| Python | ghcr.io/datadog/system-tests/dd-lib-python-init-test-django-preinstalled:latest | +| Python | ghcr.io/datadog/system-tests/dd-lib-python-init-test-django-unsupported-package-force:latest | +| Python | ghcr.io/datadog/system-tests/dd-lib-python-init-test-django-uvicorn:latest | +| Python | ghcr.io/datadog/system-tests/dd-lib-python-init-test-protobuf-old:latest | +| Ruby | ghcr.io/datadog/system-tests/dd-lib-ruby-init-test-rails:latest | +| Ruby | ghcr.io/datadog/system-tests/dd-lib-ruby-init-test-rails-explicit":latest | +| Ruby | ghcr.io/datadog/system-tests/dd-lib-ruby-init-test-rails-gemsrb:latest | + +##### Library init image + +The library init images are created by each tracer library and these images will be pushed to the registry using two tags: +* **latest:** The latest release of the image. +* **latest_snapshot:** The image created when we build the main branch of the tracer library. + +The list of available images is: + +| LANG | LIB INIT IMAGE | +|---|---| +| Java | gcr.io/datadoghq/dd-lib-java-init:latest | +| Java | ghcr.io/datadog/dd-trace-java/dd-lib-java-init:latest_snapshot | +| DotNet | gcr.io/datadoghq/dd-lib-dotnet-init:latest | +| DotNet | ghcr.io/datadog/dd-trace-dotnet/dd-lib-dotnet-init:latest_snapshot | +| Nodejs | gcr.io/datadoghq/dd-lib-js-init:latest | +| Nodejs | ghcr.io/datadog/dd-trace-js/dd-lib-js-init:latest_snapshot | +| Python | gcr.io/datadoghq/dd-lib-python-init:latest | +| Python | ghcr.io/datadog/dd-trace-py/dd-lib-python-init:latest_snapshot | +| Ruby | gcr.io/datadoghq/dd-lib-ruby-init:latest | +| Ruby | ghcr.io/datadog/dd-trace-rb/dd-lib-ruby-init:latest_snapshot | + +##### Datadog Cluster Agent + +The Datadog Cluster Agent versions available for tests are: +- 7.56.2 +- 7.57.0 +- 7.59.0 + +##### Injector image + +TODO + +#### Execute a test scenario + +If we have followed the previous steps, we already have the environment configured and we only need to run any of the available scenarios: +- **K8S_LIBRARY_INJECTION_BASIC:** Minimal test scenario that run a Kubernetes cluster and test that the application is being instrumented automatically. +- **K8S_LIBRARY_INJECTION_PROFILING:** Test profiling feature inside of Kubernetes cluster. +- **K8S_LIBRARY_INJECTION_DJM:** Allow us to verify the k8s injection continue to work for Data Jobs Monitoring as new Java tracer, new auto_inject, and new cluster_agent are being released. + +Run the minimal test scenario: ```sh ./run.sh K8S_LIBRARY_INJECTION_BASIC ``` -# Test development +##### DJM Scenario + +The following image ilustrates the DJM scenario: + +![DJM Scenario](../lib-injection/k8s_djm.png "DJM Scenario") + +## How to develop a test case + +To develop a new test case in the K8s Library injection tests, you need to know: + +- The project folder structure. +- The parameters that you will recive in your test case (Parametrized test) + +### Folders and Files structure + +The following picture shows the main directories for the k8s lib injection tests: + +![Folder structure](../lib-injection/k8s_lib_injections_folders.png "Folder structure") + +The folders and files shown in the figure above are as follows: + +* **lib-injection/build/docker:** This folder contains the sample applications with the source code and scripts that allow us to build and push docker weblog images. +* **tests/k8s_lib_injection:** All tests cases are stored on this folder. Conftests.py file manages the kubernetes cluster lifecycle. +* **utils/_context/scenarios:**: In this folder you can find the K8s Lib injection scenario definition. +* **utils/k8s_lib_injection:** Here we can find the main utilities for the control and deployment of the components to be tested. For example: + * **k8s_kind_cluster.py:** Tools for creating and destroying the Kubernetes cluster. + * **k8s_datadog_kubernetes.py:** Utils for: + - Deploy Datadog Cluster Agent + - Deploy Datadog Admission Controller + - Apply Kubernetes ConfigMap + - Extract Datadog Components debug information. + * **k8s_weblog.py:** Manages the weblog application lifecycle. + - Deploy weblog as pod configured to perform library injection manually/without the Datadog admission controller. + - Deploy weblog as pod configured to automatically perform the library injection using the Datadog admission controler. + - Deploy weblog as Kubernetes deployment and prepare the library injection using Kubernetes ConfigMaps and Datadog Admission Controller. + - Extract weblog debug information. + * **k8s_command_utils.py:** Command line utils to lauch the Helm Chart commands and others shell commands. + +### Implement a new test case -All test cases for K8S_LIB_INJECTION will run on an isolated Kubernetes environment. For each test case we are going to start up a Kubernetes Cluster. In this way we can run the tests in parallel. +All test cases for K8s will run on an isolated Kubernetes environment. For each test case we are going to start up a Kubernetes Cluster. In this way we can run the tests in parallel. Each test case will receive a "test_k8s_instance" object with these main properties loaded: * **library:** Current testing library (java, python...) * **weblog_variant:** Current sample application name (weblog name) @@ -227,38 +332,51 @@ The "test_k8s_instance" also contains some basic methods, that you can use direc * deploy_test_agent * deploy_weblog_as_pod * deploy_weblog_as_deployment -* apply_config_auto_inject * export_debug_info Feel free to use the methods listed above or use the methods encapsulated in both "k8s_datadog_cluster_agent" and "k8s_weblog" or directly use the Kubernates Python Client to manipulate the Kunernates cluster components. -An example of a Kubernetes test that uses all the APIs: +An example of a Kubernetes test: ```python + +from tests.k8s_lib_injection.utils import get_dev_agent_traces + @features.k8s_admission_controller -@scenarios.k8s_lib_injection +@scenarios.k8s_library_injection_basic class TestExample: def test_example(self, test_k8s_instance): + logger.info( + f"Test config: Weblog - [{test_k8s_instance.k8s_kind_cluster.get_weblog_port()}] Agent - [{test_k8s_instance.k8s_kind_cluster.get_agent_port()}]" + ) #Deploy test agent - test_agent = test_k8s_instance.deploy_test_agent() - #Deploy admission controller - test_agent.deploy_operator_manual() + test_k8s_instance.deploy_test_agent() + #Deploy cluster agent with admission controller + test_k8s_instance.deploy_datadog_cluster_agent() #Deploy weblog test_k8s_instance.deploy_weblog_as_pod() #Check that app was auto instrumented - response = requests.get(f"http://localhost:{test_k8s_instance.k8s_kind_cluster.agent_port}/test/traces") - traces_json = response.json() + traces_json = get_dev_agent_traces(test_k8s_instance.k8s_kind_cluster) assert len(traces_json) > 0, "No traces found" - #Use Kubernetes python client to check how many pods have been created - v1 = client.CoreV1Api(api_client=config.new_client_from_config(context=self.k8s_kind_cluster.context_name)) - ret = v1.list_namespaced_pod(namespace="default", watch=False) - assert len(ret.items) > 2, "Incorrect number of pods" ``` +You can also add environment variables to your pod, for example: + +```python + test_k8s_instance.deploy_weblog_as_pod( + env={"DD_PROFILING_UPLOAD_PERIOD": "10", "DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD": "1500"} + ) +``` + +Or you can activate DD features from the Cluster agent: -# How to debug your kubernetes environment and tests results +```python + test_k8s_instance.deploy_datadog_cluster_agent(features={"datadog.profiling.enabled": "auto"}) +``` + +## How to debug your kubernetes environment and tests results In the testing kubernetes scenarios, multiple components are involved and sometimes can be painfull to debug a failure. Even more so when running all tests in parallel. -You can find a folder named "logs_k8s_lib_injection" with separe folder per test case. +You can find a folder named "logs_[scenario name]" with a separe folder per test case. In the following image you can see the log folder content: ![Log folder structure](../lib-injection/k8s_lib_injections_log_folders.png "Log folder structure") @@ -270,7 +388,6 @@ These are the main important log/data files: * **feature_parity.json:** Report to push the results to Feature Parity Dashboard. * **lib-injection-testing-xyz-config.yaml:** The kind cluster configuration. In this file you can check the open ports for each cluster and test case. * **lib-injection-testing-xyz_help_values:** Helm chart operator values for each test case. -* **/applied_configmaps.log:** ConfigMaps applied in the testcase (it could be empty if there are no configmaps applied). * **/daemon.set.describe.log:** Datadog Cluster daemon set logs. * **/datadog-XYZ_events.log:** Kubernetes events for Datadog Agent. * **/datadog-cluster-agent-XYZ_status.log:** Datadog Cluster Agent current status. @@ -279,10 +396,43 @@ These are the main important log/data files: * **/datadog-cluster-agent-XYZ_event.log:** Kubernetes events for Datadog Cluster Agent. * **/deployment.describe.log:** Describe all deployment in the Kubernetes cluster. * **/deployment.logs.log:** All deployments logs. -* **/events_configmaps.log:** Events generated when we apply a configmap. * **/get.deployments.log:** Deployments list. * **/get.pods.log:** Current started pod list. * **/k8s_logger.log:** Specific logs for current test case. * **/myapp.describe.log:** Describe weblog pod. * **/myapp.logs.log:** Current weblog pod logs. It could be empty if we are deploying the weblog as Kubernetes deployment. * **/test-LANG-deployment-XYZ_events.log:** Current weblog deployment events. Here you can see the events generated by auto instrumention process. It could be empty if we are deploying the weblog application as Pod. + +## How to debug your kubernetes environment at runtime + +So far there is no parameter that allows to keep the kubernetes cluster alive after launching the tests. But we can make some temporary tweaks to do that. + +You only need to comment the line that stops the cluster after the test case. You can do this here: +https://github.com/DataDog/system-tests/blob/fd8766cd45687d2be4b858df611435da7f41c6d6/tests/k8s_lib_injection/conftest.py#L43C5-L43C17 + +```python + +@pytest.fixture +def test_k8s_instance(request): + test_name = request.node.name + library = "js" if context.scenario.library.library == "nodejs" else context.scenario.library.library + + # Create a folder with the test name + output_folder = f"{context.scenario.host_log_folder}/{test_name}" + if not os.path.exists(output_folder): + os.makedirs(output_folder) + + k8s_instance = K8sInstance(... ...) + logger.info(f"K8sInstance creating -- {test_name}") + k8s_instance.start_instance() + logger.info("K8sInstance created") + yield k8s_instance + logger.info("K8sInstance Exporting debug info") + k8s_instance.export_debug_info() + logger.info("K8sInstance destroying") + # k8s_instance.destroy_instance() SKIP STOP CLUSTER AFTER THE TESTS + logger.info("K8sInstance destroyed") +``` + +Although it is not very practical, we recommend to run only one test, commenting the rest of the methods/tests case the tests class. +For example, if you want to debug at runtime the k8s profiling scenario, we recommend to keep only one test case in the class "TestAdmisionControllerProfiling" (you can skip a test method adding the character "_" before the method name) https://github.com/DataDog/system-tests/blob/fd8766cd45687d2be4b858df611435da7f41c6d6/tests/k8s_lib_injection/test_k8s_manual_inject.py#L79 \ No newline at end of file diff --git a/docs/edit/lifecycle.md b/docs/scenarios/lifecycle.md similarity index 94% rename from docs/edit/lifecycle.md rename to docs/scenarios/lifecycle.md index 3c56c1b0122..aa0ffceb19a 100644 --- a/docs/edit/lifecycle.md +++ b/docs/scenarios/lifecycle.md @@ -6,4 +6,4 @@ System tests spawn several services before starting. Here is the lifecycle: 1. Starts weblog 1. Execute tests 1. Exports all images logs -1. End of process \ No newline at end of file +1. End of process diff --git a/docs/scenarios/onboarding.md b/docs/scenarios/onboarding.md index 2e91dd8747e..682d3fcf997 100644 --- a/docs/scenarios/onboarding.md +++ b/docs/scenarios/onboarding.md @@ -1,6 +1,29 @@ -# Datadog Library Injection testing - -Similarly to Library Injection in Kubernetes environments via the admission controller, Library injection simplifies the APM onboarding experience for customers deploying Java, NodeJS, .NET and Ruby applications in VMs and docker environments. +1. [Overall](#Overall) + * [Library Injection testing scenarios](#Library-Injection-testing-scenarios) + * [Knowledge concepts](#Knowledge-concepts) + - [Virtual Machine scenario](#Virtual-Machine-scenario) + - [Virtual Machine](#Virtual-Machine) + - [Provision](#Provision) + - [Provider](#Provider) +2. [Run the tests](#Run-the-tests) + * [Prerequisites](#Prerequisites) + - [AWS](#AWS) + - [Vagrant](#Vagrant) + - [Pulumi](#Pulumi) + - [System-tests requirements](#System-tests-requirements) + * [Configure the environment variables](#Configure-the-environment-variables) + * [Run the scenario](#run-the-scenario) +3. [How to develop tests](#How-to-develop-a-test-case) + * [Folders and Files structure](#Folders-and-Files-structure) + * [Create a new provision](#Create-a-new-provision) + * [Create a new weblog](#Create-a-new-weblog) + * [Create a new test case](#Create-a-new-test-case) +4. [How to debug your environment and tests results](#How-to-debug-your-environment-and-tests-results) +5. [How to debug a virtual machine at runtime](#How-to-debug-a-virtual-machine-at-runtime) + +# Overall + +Similarly to Library Injection in Kubernetes environments via the admission controller, Library injection simplifies the APM onboarding experience for customers auto-intrumenting Java, Python, NodeJS, .NET, PHP or Ruby applications running on host or in docker environments. The target of this testing feature is to test the distinct injection environments. @@ -8,80 +31,130 @@ The target of this testing feature is to test the distinct injection environment ## Library Injection testing scenarios -The automatic libray injection is tested on two scenarios: -* Datadog Agent and your application deployed on the same host ([host injection documentation](https://docs.datadoghq.com/tracing/trace_collection/library_injection/?tab=host)). -* Datadog Agent and your application installed on containers ([containers injection documentation](https://docs.datadoghq.com/tracing/trace_collection/library_injection/?tab=agentandappinseparatecontainers)). +The automatic libray injection is tested on three possible scenarios: + +* Datadog Agent and your application deployed on the same host ([host injection documentation](https://docs.datadoghq.com/tracing/trace_collection/library_injection_local/?tab=host)). +* Datadog Agent deployed on the host, your application deployed on containers ([agent on host and app in containers documentation](https://docs.datadoghq.com/tracing/trace_collection/library_injection_local/?tab=agentonhostappincontainers)). +* Datadog Agent and your application installed on containers ([containers injection documentation](https://docs.datadoghq.com/tracing/trace_collection/library_injection_local/?tab=agentandappinseparatecontainers)). > For Kubernetes Datadog library injection capabilities check the [kubernetes injection documentation](https://docs.datadoghq.com/tracing/trace_collection/library_injection_local/?tab=kubernetes) or take a look at the [kubernetes injection testing scenarios](https://github.com/DataDog/system-tests/blob/main/docs/scenarios/k8s_lib_injection.md). ## Knowledge concepts -We need to know some terms: +Before start with the onboarding tests, we need to know some terms: * **Scenario:** In system-tests, a virtual scenario is a set of: - * a tested architecture, which can be a set of virtual machines or a single virtual machine. This set of VMs will be supplied thanks to the integration of system-tests framework with different providers of this technology. - * a list of setup executed on this tested architecture, we called as a virtual machine provision. - * a list of test + * a tested architecture, which can be a software installation scripts (provision) to run on a single virtual machine. This VM will be supplied thanks to the integration of system-tests framework with different providers of this technology. + * a list of setup executed on this tested architecture, we called as a virtual machine provision. Each scenario is associated with a provision. + * a list of test associated to the scenario * **Virtual Machine:** A virtual machine (VM) is a replica, in terms of behavior, of a physical computer. There is software capable of emulating these replicas of physical computers running operating systems. In this case, system-tests will be able to handle the integration of the framework itself with the virtual machines, so that we can install our software to be tested on them (provision). - -* **Provision:** It will be the list of software and configurations to be installed on the virtual machines. The provisions will be specified by using yaml files. - +* **Provision:** It will be the list of software and configurations to be installed on the virtual machine. The provisions will be specified by using yaml files. * **Weblog:** Usually It is a web application that exposes consistent endpoints across all implementations and that will be installed on the Virtual Machine. In the case of weblogs associated to the VMs, it does not always have to be a web application that exposes services, it can also be a specific configuration for the machine we want to test. - * **Provider:** It refers to the integration of system-tests with the different technologies that allow interacting with virtual machines. These can be executed locally using software such as vmware, virtual box... or executed in the cloud using services such as Google Cloud or AWS. - * **Tests:** Set of tests to run against a virtual machine. For example, we can make remote HTTP requests to an installed web application during the provisioning process or we can connect to it via SSH to execute different commands to check that the installed software provision is running correctly. -### Define a Virtual Machine scenario +![SSI tests architecture](../lib-injection/onboarding_overview.png "SSI tests architecture") + +### Virtual Machine scenario +You can create your own VirtualMachine scenario, extending the common interface `_VirtualMachineScenario`, and specifing the allowed machines and the default provision. In the following code you can see how we define a new VirtualMachine Scenario, setting the VMs that you want to run: ```Python - host_auto_injection = _VirtualMachineScenario( - "HOST_AUTO_INJECTION", - vm_provision="host-auto-inject", - doc="Onboarding Host Single Step Instrumentation scenario", - include_ubuntu_22_amd64=True, - include_ubuntu_22_arm64=True, - include_ubuntu_18_amd64=False, - include_amazon_linux_2_amd64=False, - include_amazon_linux_2_dotnet_6=True, - include_amazon_linux_2023_amd64=True, - include_amazon_linux_2023_arm64=True, - ) +class InstallerAutoInjectionScenarioProfiling(_VirtualMachineScenario): + + def __init__( + self, + name, + doc, + vm_provision="installer-auto-inject", #Reference to the provision for this scenario + agent_env=None, + app_env=None, + scenario_groups=None, + github_workflow=None, + ) -> None: + # Specific configuration for the weblogs deployed using this scenario + app_env_defaults = { + "DD_TRACE_RATE_LIMIT": "1000000000000", + "DD_TRACE_SAMPLING_RULES": "'[{\"sample_rate\":1}]'", + } + if app_env is not None: + app_env_defaults.update(app_env) + + super().__init__( + name, + vm_provision=vm_provision, + agent_env=agent_env, + app_env=app_env_defaults, + doc=doc, + github_workflow=github_workflow, + include_ubuntu_22_amd64=True, + include_ubuntu_22_arm64=True, + include_amazon_linux_2_amd64=True, + include_amazon_linux_2_arm64=True, + include_amazon_linux_2023_amd64=True, + include_amazon_linux_2023_arm64=True, + include_redhat_7_9_amd64=True, + include_redhat_8_amd64=True, + include_redhat_8_arm64=True, + include_redhat_9_amd64=True, + include_redhat_9_arm64=True, + scenario_groups=scenario_groups, + ) ``` + ### Virtual Machine -The Virtual Machines are defined in utils/_context/virtual_machines.py. -There are some predefined machines. For example: +The Virtual Machines properties: + +* There are defined in `utils/_context/virtual_machines.py`. +* The id/name must be unique. +* Each machine must extend the interface: `_VirtualMachine`. +* There are some fields to configure the machine depends of the selected provider: + * **aws_config:** Mandatory. AWS configuration: ami ID, instance type, user. The AMI id must exist on your AWS account. + * **vagrant_config:** Optional. Vagrant image to be used. + * **krunvm_config:** Optional. Docker image to be used with the Krumvn provider (deprecated). +* There are some fields, that allow us to categorize the machine: + * **os_type:** Operating System type. Usually set to Linux. But it might be Windows or Mac. + * **os_distro:** Refers to Linux distribution or package manager type. Usually "deb" or "rpm". + * **os_branch:** Open field, to categorize the machine. + * **os_cpu:** Architecture: amd64 or arm64. + * **default_vm:** Field that allow us to split or group the machine as default or not default. Related with the CI policies. ```Python class Ubuntu22amd64(_VirtualMachine): def __init__(self, **kwargs) -> None: super().__init__( "Ubuntu_22_amd64", - aws_config=_AWSConfig(ami_id="ami-007855ac798b5175e", ami_instance_type="t2.medium", user="ubuntu"), + aws_config=_AWSConfig(ami_id="ami-007855ac798b5175e", ami_instance_type="t3.medium", user="ubuntu"), vagrant_config=_VagrantConfig(box_name="bento/ubuntu-22.04"), + krunvm_config=None, os_type="linux", os_distro="deb", os_branch="ubuntu22_amd64", os_cpu="amd64", + default_vm=False, **kwargs, ) ``` + ### Provision + We call provision to the configurations applied or the software installed on the machines included in the scenario. Some properties of the provisions in system-tests are as follows: -* They are defined in the Yaml files. -* They Yaml file will be located in the folder: utils/build/virtual_machine/provisions/ -* The installation of the Weblog is also defined on Yaml files, but will be located in a different folder: utils/build/virtual_machine/weblogs// +* There are defined in the Yaml files. +* There are two types of provisions: + * **Scenario provision:** Configuration and installations to prepare the environment. For example, install docker and install the Datadog SSI software. + * **Weblog provision:** Steps and configurations to deploy the weblog/ sample application. +* In a test execution the both types of provisions are involved (We allways set by the command line the scenario name and the weblog name). +* The scenario provision is a Yaml file and it is located in the folder: `utils/build/virtual_machine/provisions/[provision_name]` , using the file name `provision.yml` +* The installation of the Weblog (weblog provision) is also defined on Yaml files, but is located in a different folder, `utils/build/virtual_machine/weblogs/[lang]/`. It uses the file name `provision_[weblog].yml`. * Each provision is different, therefore, different installation steps may be defined. -* All provisions may define their own installation steps, but they must contain some mandatory definition steps. For example, all provisions will have to define a step that extracts the names and versions of installed components we want to test. +* All provisions may define their own installation steps, but they must contain some mandatory definition steps. For example, all provisions must define a step that extracts the names and versions of installed components we want to test. * The same provision must be able to be installed on different operating systems and architectures. -* The selection of the provision to install in a virtual machine, is the responsibility of the python code that can be found at utils/virtual_machine/virtual_machine_provisioner.py This is an example of provision file: @@ -156,7 +229,7 @@ install-agent: Some of the sections listed above are detailed as follows: -* **init-environment:** They are variables that will be loaded depending on the execution environment (env=dev or env=prod). These variables will be populated in all commands executed on the machines. +* **init-environment:** They are variables that will be loaded depending on the execution environment (env=dev or env=prod). **These variables will be populated in all commands executed on the machines**. * **tested_components:** This is a mandatory field. We should extract the components that we are testing. The result of the command should be a json string. As you can see the install section could be split by “os_type“ and “os_distro“ fields. You could define a command for all the machines or you could define commands by the machine type. The details of the "installation" field are explained later. * **provision_steps:** In this section you must define the steps for the whole installation. In this case we have three steps: * init-config: Represent a step that will run the same command for all types of the linux machines. @@ -184,24 +257,58 @@ my-step: local_path: utils/build/test.service remote-command: echo "This command will run on remote machine" ``` + +You can define a provision that can be installed on a different machine types, architectures or OS: + +```yaml +my-step: + install: + - os_type: linux + os_distro: rpm #Run for rpm machines + local-command: echo "This command will run on local" + copy_files: + - name: copy-this-file-to-home-folder-on-remote-machine + local_path: utils/build/test.service + remote-command: echo "This command will run on a RPM based remote machine" + + - os_type: linux + os_distro: deb #Run for deb machines + local-command: echo "This command will run on local" + copy_files: + - name: copy-this-file-to-home-folder-on-remote-machine + local_path: utils/build/test.service + remote-command: echo "This command will run on a debian based remote machine" + + - os_type: linux + os_distro: deb #Run for deb machines + os_cpu: arm64 #Run only for arm based machines + local-command: echo "This command will run on local" + copy_files: + - name: copy-this-file-to-home-folder-on-remote-machine + local_path: utils/build/test.service + remote-command: echo "This command will run on a debian based remote machine (only for arm64 architectures)" +``` + ### Provider We currently support two providers: * **Pulumi AWS:** Using Pulumi AWS we can create and manage EC2 instances. -* **Vagrant:** Vagrant enables users to create and configure lightweight, reproducible, and portable development local environments. +* **Vagrant:** Vagrant enables users to create and configure lightweight, reproducible, and portable development local environments (Beta feature). -We can find the developed providers in the folder: utils/virtual_machine. -We can select the correct provider for out configured environment using the factory located on utils/virtual_machine/virtual_machine_provider.py. +We can find the available providers in the folder: `utils/virtual_machine.` +The common interface that implemets all the existing providers is: `utils/virtual_machine/virtual_machine_provider.py`. + +# Run the tests ## Prerequisites -To test scenarios mentioned above, We will use the following utilities: +To run the onboarding test scenarios, we will use the following utilities: -* AWS as the infrastructure provider: We are testing onboarding installation scenarios on different types of machines and OS. AWS Cli must be configured on your computer in order to launch EC2 instances automatically. -* Vagrant as the infrastructure local provider: For local executions, we can use Vagrant instead of AWS EC2 instances. -* Pulumi as the orchestrator of this test infrastructure: Pulumi's open source infrastructure as code SDK enables you to create, deploy, and manage infrastructure on any cloud, using your favorite languages. -* Pytest as testing tool (Python): System-tests is built on Pytest. +* **AWS as the infrastructure provider:** We are testing onboarding installation scenarios on different types of machines and OS. AWS Cli must be configured on your computer in order to launch EC2 instances automatically. +* **Vagrant as the infrastructure local provider**: For local executions, we can use Vagrant instead of AWS EC2 instances. +* **Pulumi as the orchestrator of this test infrastructure:** Pulumi's open source infrastructure as code SDK enables you to create, deploy, and manage infrastructure on any cloud, using your favorite languages. +* **Pytest as testing tool (Python):** System-tests is built on Pytest. ### AWS @@ -211,6 +318,8 @@ In order to securely store and access AWS credentials in an our test environment ### Vagrant +The Vagrant support is a system-tests beta feature. To run the tests using the Vagrant provider, you should install: + * Install Vagrant Install Vagrant | Vagrant | HashiCorp Developer * Install QEMU emulator: Download QEMU - QEMU * Install python Vagrant plugin: python-vagrant @@ -221,23 +330,23 @@ In order to securely store and access AWS credentials in an our test environment Pulumi is a universal infrastructure as code platform that allows you to use familiar programming languages and tools to build, deploy, and manage cloud infrastructure. Please install and configure as described in the [following documentation](https://www.pulumi.com/docs/get-started/aws/) -### Pytest +--- -All system-tests assertions and utilities are based on python and pytests. Check the documentation to configure your python environment: [system-tests requirements](https://github.com/DataDog/system-tests/blob/main/docs/execute/requirements.md) +**NOTE:** -## Run the tests +if it's the first time you execute the Pulimi, you probably need to run the command: `pulumi login --local` +[Pulumi login](https://www.pulumi.com/docs/reference/cli/pulumi_login/) -### Before run +--- -Before run the onboarding tests you should configure: +### System-tests requirements -- Python environment as described: [configure python for system-tests](https://github.com/DataDog/system-tests/blob/main/docs/execute/requirements.md). -- Ensure that requirements.txt is loaded (you can run "./build.sh -i runner") -- AWS Cli is configured -- Pulumi environment configured as described: [Get started with Pulumi](https://www.pulumi.com/docs/get-started/) - - Execute "pulumi login" local step: [Pulumi login](https://www.pulumi.com/docs/reference/cli/pulumi_login/). +All system-tests assertions and utilities are based on python and pytests. You need to prepare this environment before run the tests: -### Configure environment +- Python and pytests environment as described: [configure python and pytests for system-tests](../../README.md#requirements). +- Ensure that requirements.txt is loaded (you can run "`./build.sh -i runner`") + +## Configure the environment variables Before execute the "onboarding" tests you must configure some environment variables: @@ -246,37 +355,314 @@ Before execute the "onboarding" tests you must configure some environment variab - **DD_API_KEY_ONBOARDING:** Datadog API key. - **DD_APP_KEY_ONBOARDING:** Datadog APP key. -To debug purposes you can create and use your own EC2 key-pair. To use it you should configure the following environment variables: +To debug purposes you can create and use your own EC2 key-pair. You can read this tutorial to do that: [Create a key pair for your Amazon EC2 instance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/create-key-pairs.html) +Once the key has been created, you can use it configuring the following environment variables: - **ONBOARDING_AWS_INFRA_KEYPAIR_NAME:** Set key pair name to ssh connect to the remote machines. - **ONBOARDING_AWS_INFRA_KEY_PATH:** Local absolute path to your keir-pair file (pem file). -Opcionally you can set extra parameters to filter the type of tests that you will execute: - -- **ONBOARDING_FILTER_OS_DISTRO:** Test only on a machine type (for instance 'deb' or 'rpm') - -### Run script +## Run the scenario The 'onboarding' tests can be executed in the same way as we executed system-tests scenarios. The currently supported scenarios are the following: -* **HOST_AUTO_INJECTION:** Onboarding Host Single Step Instrumentation scenario -* **SIMPLE_HOST_AUTO_INJECTION:** Onboarding Host Single Step Instrumentation scenario (minimal test scenario) -* **SIMPLE_HOST_AUTO_INJECTION_PROFILING:** Onboarding Host Single Step Instrumentation profiling scenario (minimal test scenario) -* **HOST_AUTO_INJECTION_BLOCK_LIST:** Onboarding Host Single Step Instrumentation scenario: Test user defined blocking lists -* **HOST_AUTO_INJECTION_INSTALL_SCRIPT:** Onboarding Host Single Step Instrumentation scenario using agent auto install script -* **HOST_AUTO_INJECTION_INSTALL_SCRIPT_PROFILING:** Onboarding Host Single Step Instrumentation scenario using agent auto install script with enabling profiling -* **CONTAINER_AUTO_INJECTION:** Onboarding Container Single Step Instrumentation scenario -* **SIMPLE_CONTAINER_AUTO_INJECTION:** Onboarding Container Single Step Instrumentation scenario (minimal test scenario) -* **CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT:** Onboarding Container Single Step Instrumentation scenario using agent auto install script +* **SIMPLE_INSTALLER_AUTO_INJECTION:** The onboarding minimal scenario. The test makes a request to deployed weblog application and then check that the instrumentation traces are sending to the backend. +* **INSTALLER_AUTO_INJECTION:** Inlcudes the minimal scenario assertions but adding other assertions like the uninstall process or the block list commands tests. For the containerized app, the agent will run on host, and the app in a docker container. +* **INSTALLER_NOT_SUPPORTED_AUTO_INJECTION:** Onboarding Single Step Instrumentation scenario for not supported runtime language versions. After install the SSI software this scenario checks that the application is not auto instrumented (because the runtime version is not supported), but continues working. +* **CHAOS_INSTALLER_AUTO_INJECTION:** Checks the SSI after performing actions that are not recommended. For example, delete installation folder and others. The system must be recoverable. +* **SIMPLE_AUTO_INJECTION_PROFILING:** Onboarding Single Step Instrumentation scenario with profiling activated by the environment variables on the sample application. +* **HOST_AUTO_INJECTION_INSTALL_SCRIPT_PROFILING:** Onboarding Host Single Step Instrumentation scenario using agent auto install script with profiling activating by the installation process +* **CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT_PROFILING:** Onboarding Container Single Step Instrumentation profiling scenario using agent auto installation script. +* **HOST_AUTO_INJECTION_INSTALL_SCRIPT:** Onboarding Host Single Step Instrumentation scenario using agent auto installation script. +* **CONTAINER_AUTO_INJECTION_INSTALL_SCRIPT:** Onboarding Container Single Step Instrumentation scenario using agent auto installation script. The agent and the app will run on a separate containers. -The 'onboarding' tests scenarios requiered three mandatory parameters: +The 'onboarding' tests scenarios required these mandatory parameters: -- **--vm-library:** Configure language to test (currently supported languages are: java, python, nodejs, dotnet) +- **--vm-library:** Configure language to test (currently supported languages are: java, python, nodejs, dotnet, php) - **--vm-env:** Configure origin of the software: dev (beta software) or prod (releases) -- **--vm-weblog:** Configure weblog to tests +- **--vm-weblog:** Configure weblog name to tests. The provision file should exist: `utils/build/virtual_machine/weblogs/LANG/provision_WEBLOG-NAME.yml` - **--vm-provider:** Default "aws" +- **--vm-only:** The virtual machine name, where we'll install the scenario provision. You can find all the allowed Virtual Machines: `utils/_context/virtual_machines.py` The following line shows an example of command line to run the tests: - - './run.sh SIMPLE_HOST_AUTO_INJECTION --vm-weblog test-app-nodejs --vm-env dev --vm-library nodejs --vm-provider aws' +```bash +export ONBOARDING_AWS_INFRA_SUBNET_ID=subnet-xyz +export ONBOARDING_AWS_INFRA_SECURITY_GROUPS_ID=sg-xyz +export DD_API_KEY_ONBOARDING=apikey +export DD_APP_KEY_ONBOARDING=appkey +export ONBOARDING_LOCAL_TEST="true" + +./run.sh SIMPLE_INSTALLER_AUTO_INJECTION --vm-weblog test-app-nodejs --vm-env dev --vm-library nodejs --vm-provider aws --vm-only Ubuntu_22_amd64 +``` + +# How to develop tests + +Developing new tests might involve one or several operations: + +* **Implement a new provision/scenario:** You need a custom provision or extra steps. For example, in addition to the SSI software you want to install a several linux services to check if these services can interfere on the weblog auto injection. +* **Add a new weblog:** You want to add a new weblog to be tested in the previously existing scenario. +* **Add a new test case:** You want to add new assertions against the existing scenarios and weblogs. + +## Folders and Files structure + +To develop a new test case in the SSI Library injection tests, you need to know about the project folder structure. +The following picture shows the main directories for the SSI tests: + +![Folder structure](../lib-injection/ssi_lib_injections_folders.png "Folder structure") + +* **lib-injection/build/docker:** This folder contains the sample applications source code. +* **tests/auto_inject:** All tests cases are stored on this folder. +* **utils/_context/scenarios/**: In this folder you can find the SSI Lib injection scenario definition. +* **utils/_context/virtual_machines.py:** The virtual machine definition file. +* **utils/build/virtual_machine/provisions/:** Provisions associated to the scenario. +* **utils/build/virtual_machine/weblogs/:** Provisions associated to the weblogs. +* **utils/onboarding:** Utilities that are used from the test cases. For example, make a request to the weblog or make queries to the backend in order to find the generated instrumentation traces. +* **utils/virtual_machine/:** The core implementation of this test framework. For example, the provider implementation, the pulumi wrapper or the provision files parser. +* **.gitlab-ci.yml:** These tests are launched on GitLab. + +## Create a new provision + +If you want to create a new machine provision, first you need to define a new scenario and associate it with a new provision. For example (`utils/_context/_scenarios/__init__.py`): + +```python + my_custom_scenario= InstallerAutoInjectionScenario( + "MY_CUSTOM_SCENARIO", + "A very simple example", + vm_provision="my_provision" + ) +``` + +We should define the provision. Let's create a folder named: `utils/build/virtual_machine/provisions/my_provision` and add the file `provision.yml`: + +```yaml + +# Optional: Load the environment variables +init-environment: + #This variables will be populated as env variables in all commands for each provision installation + - env: dev + MY_VAR: DEV_VAR + - env: prod + MY_VAR: PROD_VAR + agent_dist_channel: stable + agent_major_version: "7" + +# Mandatory: Scripts to extract the installed/tested components +tested_components: + install: + - os_type: linux + remote-command: | + echo "{'test_component':'1.0.0'}" + + +# Mandatory: Steps to provision VM +provision_steps: + - my-custom-step + +my-custom-step: + cache: false + install: + - os_type: linux + remote-command: echo "Hey! Hello $MY_VAR!" +``` + +This scenario provision will be installed when you run the scenario: + +```bash +export ONBOARDING_AWS_INFRA_SUBNET_ID=subnet-xyz +export ONBOARDING_AWS_INFRA_SECURITY_GROUPS_ID=sg-xyz +./run.sh MY_CUSTOM_SCENARIO --vm-weblog test-app-nodejs --vm-env dev --vm-library nodejs --vm-provider aws --vm-only Ubuntu_22_amd64 +``` + +## Create a new weblog + +You can add more weblogs to the existing scenarios. You must follow some rules: + +* The weblog provision is located in the folder: `utils/build/virtual_machine/weblogs/LANG` +* The weblog provision is defined in the file: `provision_WEBLOG_NAME.yml` +* There are two types of weblogs, host based apps and containerized apps. +* The weblog provision contains two main sections: + * lang_variant: Optional. If you are creating a host based app, you must install the language runtime before. + * weblog: The weblog provision. Copy files and configuration, compile and run as service. +* If you ar creating a host based app, you should run the app as system service called: *test-app-service*. + +This is an example of Java app running on host. We called the weblog as `my_custom_app`, we define the file `provision_my_custom_app.yml` in `utils/build/virtual_machine/weblogs/java` folder: + +```yaml +lang_variant: + name: DefaultJDK + version: default + cache: true + install: + + - os_type: linux + os_distro: deb + remote-command: sudo apt-get -y update && sudo apt-get -y install default-jdk + + - os_type: linux + os_distro: rpm + remote-command: sudo sudo dnf -y install java-devel || sudo yum -y install java-devel + +weblog: + name: my_custom_app + install: + - os_type: linux + + copy_files: + - name: copy-service + local_path: utils/build/virtual_machine/weblogs/common/test-app.service + + - name: copy-service-run-script + local_path: utils/build/virtual_machine/weblogs/common/create_and_run_app_service.sh + + - name: copy-compile-weblog-script + local_path: utils/build/virtual_machine/weblogs/java/test-app-java/compile_app.sh + + - name: copy-run-weblog-script + local_path: utils/build/virtual_machine/weblogs/java/test-app-java/test-app-java_run.sh + + - name: copy-java-app + local_path: lib-injection/build/docker/java/jetty-app + + remote-command: sh test-app-java_run.sh +``` + +You can run this weblog: + +```bash +export ONBOARDING_AWS_INFRA_SUBNET_ID=subnet-xyz +export ONBOARDING_AWS_INFRA_SECURITY_GROUPS_ID=sg-xyz +./run.sh MY_CUSTOM_SCENARIO --vm-weblog my_custom_app --vm-env dev --vm-library java --vm-provider aws --vm-only Ubuntu_22_amd64 +``` + +## Create a new test case + +Implement a new test case is as simple as the rest of the existing test cases in system-tests. There is only one particularity to consider. The test methods must be parametrized. In this parameter, you can find all the data/description related with the virtual machine that we are testing. With this data, you will be able to execute remote command using SSH and retrieve the results. You can also access to the sample application Http endpoints. + +```python +@features.installer_auto_instrumentation +@scenarios.simple_installer_auto_injection +class TestSimpleInstallerAutoInjectManual(): + def test_install(self, virtual_machine): + pass +``` + +You can use the `virtual_machine` parameter to execute commands remotely: + +```python +@features.installer_auto_instrumentation +@scenarios.simple_installer_auto_injection +class TestSimpleInstallerAutoInjectManual(): + def test_install(self, virtual_machine): + assert self.execute_command(virtual_machine, "echo 'Hello'") == "Hello", "Cannot execute command on the remote machine" + + def execute_command(self, virtual_machine, command) -> str: + # Env for the command + prefix_env = "" + for key, value in virtual_machine.get_command_environment().items(): + prefix_env += f"export {key}={value} \n" + + command_with_env = f"{prefix_env} {command}" + + with virtual_machine.ssh_config.get_ssh_connection() as ssh: + timeout = 120 + + _, stdout, _ = ssh.exec_command(command_with_env, timeout=timeout + 5) + stdout.channel.set_combine_stderr(True) + + # Enforce that even if we reach the 2min mark we can still have a partial output of the command + # and thus see where it is stuck. + Timer(timeout, self.close_channel, (stdout.channel,)).start() + + # Read the output line by line + command_output = "" + for line in stdout.readlines(): + if not line.startswith("export"): + command_output += line + + return command_output +``` + +You can use the `virtual_machine` parameter to make request to the deployed weblog: + +```python +@features.installer_auto_instrumentation +@scenarios.simple_installer_auto_injection +class TestSimpleInstallerAutoInjectManual(): + def test_install(self, virtual_machine): + vm_ip = virtual_machine.get_ip() + vm_port = virtual_machine.deffault_open_port + vm_context_url = f"http://{vm_ip}:{vm_port}{virtual_machine.get_deployed_weblog().app_context_url}" + + #Waits for app gets ready + wait_for_port(vm_port, vm_ip, 80.0) + + #Make a http request + res = requests.get(vm_context_url) + assert res.status == 200, "Weblog is not working" +``` + +# How to debug your environment and tests results + +In the virtual machine scenarios, multiple components are involved and sometimes can be painfull to debug a failure. You can find a folder named "logs_[scenario name]" with all the logs associated with the execution In the following image you can see the log folder content: + +![Log folder structure](../lib-injection/ssi_lib_injections_log_folders.png "Log folder structure") + +These are the main important log/data files: + +* **test.log:** General log generated by system-tests. Here you will see the Pulumi outputs of the remote provisions. +* **report.json:** Pytest results report. +* **feature_parity.json:** Report to push the results to Feature Parity Dashboard. +* **report.json:** Pytest results report. +* **[vm name].log:** Logs related with the remote commands executed on the machine. +* **vms_desc.log:** Contains the IP assigned to the remote machine. +* **tested_components.log:** Contains a JSON with the versions of the components that are being tested in this scenario. +* **[machine name]/var/log/datadog/:** In this folder you will see the outputs of the datadog agent and all related deployed components. +* **[machine name]/var/log/datadog_weblog/app.log:** Logs produced by the weblog application. + +# How to debug a virtual machine at runtime + +Locally you can debug the remote machine by SSH. To do that you only need: + +* Keep alive the machine after the test execution. +* Use your own AWS key-pair to configure the SSH connection and connect to the machine ([Create a key pair for your Amazon EC2 instance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/create-key-pairs.html)). + +You can do that using the environment variables. For example: + +```bash +#Mandatory env variables +export ONBOARDING_AWS_INFRA_SUBNET_ID=subnet-xyz +export ONBOARDING_AWS_INFRA_SECURITY_GROUPS_ID=sg-xyz +export DD_API_KEY_ONBOARDING=apikey +export DD_APP_KEY_ONBOARDING=appkey + +#The key pair configuration +export ONBOARDING_AWS_INFRA_KEYPAIR_NAME="my_key_pair" +export ONBOARDING_AWS_INFRA_KEY_PATH="/home/my_user/key_pairs/my_key_pair.pem" + +#Variables to keep alive the machine after run the tests +export ONBOARDING_KEEP_VMS="true" +export ONBOARDING_LOCAL_TEST="true" + +#Run the tests +./run.sh SIMPLE_INSTALLER_AUTO_INJECTION --vm-weblog test-app-nodejs --vm-env dev --vm-library nodejs --vm-provider aws --vm-only Ubuntu_22_amd64 + +``` + +After the test execution, you will need to open the log file "logs_folder/vms_desc.log" to get the remote machine IP, after that, you should be able to access to the machine in a interactive shell: + +```bash +ssh -i "/home/my_user/key_pairs/my_key_pair.pem" ec2-user@99.99.99.99 +``` + +You can also use SCP to upload and download files to/from the remote machine: + +```bash +scp -i "/home/my_user/key_pairs/my_key_pair.pem" ubuntu@99.99.99.99:/home/ubuntu/javaagent-example/hola.txt . +``` + +Remember destroy the pulumi stack to shutdown and remove the ec2 instance: + +```bash +pulumi destroy +``` \ No newline at end of file diff --git a/docs/scenarios/parametric.md b/docs/scenarios/parametric.md index 65f3f0bf261..6d1eb733a22 100644 --- a/docs/scenarios/parametric.md +++ b/docs/scenarios/parametric.md @@ -7,26 +7,53 @@ This enables us to write unit/integration-style test cases that can be shared. Example: ```python -@parametrize("library_env", [{"DD_ENV": "prod"}, {"DD_ENV": "dev"}]) -def test_tracer_env_environment_variable(library_env, test_library, test_agent): - with test_library: - with test_library.start_span("operation"): - pass - - traces = test_agent.traces() - trace = find_trace_by_root(traces, Span(name="operation")) - assert len(trace) == 1 - - span = find_span(trace, Span(name="operation")) - assert span["name"] == "operation" - assert span["meta"]["env"] == library_env["DD_ENV"] +from utils.parametric.spec.trace import find_span, find_trace, find_span_in_traces, find_first_span_in_trace_payload, find_root_span + +@pytest.mark.parametrize("library_env", [{"DD_ENV": "prod"}]) +def test_datadog_spans(library_env, test_library, test_agent): + with test_library: + with test_library.dd_start_span("operation") as s1: + with test_library.dd_start_span("operation1", service="hello", parent_id=s1.span_id) as s2: + pass + + with test_library.dd_start_span("otel_rocks") as os1: + pass + + # Waits for 2 traces to be captured and avoids sorting the received spans by start time + # Here we want to perserve the order of spans to easily access the chunk root span (first span in payload) + traces = test_agent.wait_for_num_traces(2, sort_by_start=False) + assert len(traces) == 2, traces + + trace1 = find_trace(traces, s1.trace_id) + assert len(trace1) == 2 + + span1 = find_span(trace1, s1.span_id) + # Ensure span1 is the root span of trace1 + assert span1 == find_root_span(trace1) + assert span1["name"] == "operation" + + span2 = find_span(trace1, s2.span_id) + assert span2["name"] == "operation1" + assert span2["service"] == "hello" + + # Chunk root span can be span1 or span2 depending on how the trace was serialized + # This span will contain trace level tags (ex: _dd.p.tid) + first_span = find_first_span_in_trace_payload(trace1) + # Make sure trace level tags exist on the chunk root span + assert "language" in first_span["meta"] + assert first_span["meta"]["env"] == "prod" + + # Get one span from the list of captured traces + ospan = find_span_in_traces(traces, os1.trace_id, os1.span_id) + assert ospan["resource"] == "otel_rocks" + assert ospan["meta"]["env"] == "prod" ``` - This test case runs against all the APM libraries and is parameterized with two different environments specifying two different values of the environment variable `DD_ENV`. -- The test case creates a new span and sets a tag on it using the shared GRPC/HTTP interface. -- The implementations of the GRPC/HTTP interface, by language, are in `utils/build/docker//parametric`. +- `test_library.dd_start_span` creates a new span using the shared HTTP interface. +- The request is sent to a HTTP server by language. Implementations can be found in `utils/build/docker//parametric`. More information in [Http Server Implementations](#http-server-implementations). - Data is flushed to the test agent after the with test_library block closes. -- Data is retrieved using the `test_agent` fixture and asserted on. +- Data (usually traces) are retrieved using the `test_agent` fixture and we assert that they look the way we'd expect. ## Usage @@ -39,17 +66,12 @@ Make sure you're in the root of the repository before running these commands. The following dependencies are required to run the tests locally: - Docker -- Python >= 3.7 (for Windows users, Python 3.9 seems to run best without issues) - -then, run the following command, which will create a Python virtual environment and install the Python dependencies from the root directory: - -```sh -./build.sh -i runner -``` - +- Python 3.12 ### Running the tests +Build will happen at the beginning of the run statements. + Run all the tests for a particular tracer library: ```sh @@ -70,136 +92,49 @@ TEST_LIBRARY=dotnet ./run.sh PARAMETRIC -k test_metrics_ Tests can be aborted using CTRL-C but note that containers maybe still be running and will have to be shut down. -#### Go - -For running the Go tests, see the README in apps/golang. - -To test unmerged PRs locally, run the following in the utils/build/docker/golang/parametric directory: - -```sh -go get -u gopkg.in/DataDog/dd-trace-go.v1@ -go mod tidy -``` +### Running the tests for a custom tracer +To run tests against custom tracer builds, refer to the [Binaries Documentation](../execute/binaries.md) -#### dotnet - -Add a file datadog-dotnet-apm-.tar.gz in binaries/. must be a valid version number. - -#### Java - -##### Run Parametric tests with a custom Java Tracer version - -1. Build Java Tracer artifacts +#### After Testing with a Custom Tracer: +Note: Most of the ways to run system-tests with a custom tracer version involve modifying the binaries directory. Modifying the binaries will alter the tracer version used across your local computer. Once you're done testing with the custom tracer, ensure you **remove** it. For example for Python: ```bash -git clone git@github.com:DataDog/dd-trace-java.git -cd dd-trace-java -./gradlew :dd-java-agent:shadowJar :dd-trace-api:jar +rm -rf binaries/python-load-from-pip ``` -2. Copy both artifacts into the `system-tests/binaries/` folder: - * The Java tracer agent artifact `dd-java-agent-*.jar` from `dd-java-agent/build/libs/` - * Its public API `dd-trace-api-*.jar` from `dd-trace-api/build/libs/` into - -Note, you should have only TWO jar files in `system-tests/binaries`. Do NOT copy sources or javadoc jars. +### Using Pytest -3. Run Parametric tests from the `system-tests/parametric` folder: +The tests are executed using pytest. Below are some common command-line options you can use to control and customize your test runs. +- `-k EXPRESSION`: Run tests that match the given expression (substring or pattern). Useful for running specific tests or groups of tests. -```bash -TEST_LIBRARY=java ./run.sh test_span_sampling.py::test_single_rule_match_span_sampling_sss001 +```sh +TEST_LIBRARY=dotnet ./run.sh PARAMETRIC -k test_metrics_msgpack_serialization_TS001 ``` - -#### PHP - -##### To run with a custom build - -- Place `datadog-setup.php` and `dd-library-php-[X.Y.Z+commitsha]-aarch64-linux-gnu.tar.gz` (or the `x86_64` if you're not on ARM) in `/binaries` folder - - You can download those from the `build_packages/package extension` job artifacts, from a CI run of your branch. -- Copy it in the binaries folder - -##### Then run the tests - -From the repo root folder: - -- `./build.sh -i runner` -- `TEST_LIBRARY=php ./run.sh PARAMETRIC` or `TEST_LIBRARY=php ./run.sh PARAMETRIC -k ` - -> :warning: **If you are seeing DNS resolution issues when running the tests locally**, add the following config to the Docker daemon: - -```json - "dns-opts": [ - "single-request" - ], +- `-L`: To specifiy a language using an argument rather than env +```sh +./run.sh PARAMETRIC -L dotnet -k test_metrics_msgpack_serialization_TS001 ``` - -#### Python - -To run the Python tests "locally" push your code to a branch and then specify ``PYTHON_DDTRACE_PACKAGE``. - +- `-v`: Increase verbosity. Shows each test name and its result (pass/fail) as they are run. ```sh -TEST_LIBRARY=python PYTHON_DDTRACE_PACKAGE=git+https://github.com/Datadog/dd-trace-py@2.x ./run.sh PARAMETRIC [-k ...] +TEST_LIBRARY=dotnet ./run.sh PARAMETRIC -v ``` -#### NodeJS - -There is two ways for running the NodeJS tests with a custom tracer: -1. Create a file `nodejs-load-from-npm` in `binaries/`, the content will be installed by `npm install`. Content example: - * `DataDog/dd-trace-js#master` -2. Clone the dd-trace-js repo inside `binaries` - -#### Ruby - -There is two ways for running the Ruby tests with a custom tracer: - -1. Create an file ruby-load-from-bundle-add in binaries/, the content will be installed by bundle add. Content example: -gem 'ddtrace', git: "https://github.com/Datadog/dd-trace-rb", branch: "master", require: 'ddtrace/auto_instrument' -2. Clone the dd-trace-rb repo inside binaries - -#### C++ - -There is two ways for running the C++ library tests with a custom tracer: -1. Create a file `cpp-load-from-git` in `binaries/`. Content examples: - * `https://github.com/DataDog/dd-trace-cpp@main` - * `https://github.com/DataDog/dd-trace-cpp@` -2. Clone the dd-trace-cpp repo inside `binaries` - -The parametric shared tests can be run against the C++ library, -[dd-trace-cpp][1], this way: -```console -$ TEST_LIBRARY=cpp ./run.sh PARAMETRIC -``` +- `-vv`: Even more verbose output. Provides detailed information including setup and teardown for each test. -Use the `-k` command line argument, which is forwarded to [pytest][2], to -specify a substring within a particular test file, class, or method. Then only -matching tests will run, e.g. -```console -$ TEST_LIBRARY=cpp ./run.sh PARAMETRIC -k test_headers +```sh +TEST_LIBRARY=dotnet ./run.sh PARAMETRIC -vv -k test_metrics_ ``` -It's convenient to have a pretty printer for the tests' XML output. I use -[xunit-viewer][3]. -```console -$ npm install junit-viewer -g -``` +- `-s`: Disable output capture. Allows you to see print statements and logs directly in the console. -My development iterations then involve running the following at the top of the -repository: -```console -$ TEST_LIBRARY=cpp ./run.sh PARAMETRIC -k test_headers; xunit-viewer -r logs_parametric/reportJunit.xml +```sh +TEST_LIBRARY=dotnet ./run.sh PARAMETRIC -s ``` -This will create a file `index.html` at the top of the repository, which I then -inspect with a web browser. - -The C++ build can be made to point to a different GitHub branch by modifying the -`FetchContent_Declare` command's `GIT_TAG` argument in [CMakeLists.txt][4]. - -In order to coerce Docker to rebuild the C++ gRPC server image, one of the build -inputs must change, and so whenever I push changes to the target branch, I also -modify a scratch comment in `CMakeLists.txt` to trigger a rebuild on the next -test run. +### Understanding the test outcomes +Please refer to this [chart](docs/execute/test-outcomes.md) ### Debugging @@ -209,6 +144,7 @@ These can be used to debug the test case. The output also contains the commands used to build and run the containers which can be run manually to debug the issue further. +The logs are contained in this folder: `./logs_parametric` ## Troubleshooting @@ -217,12 +153,14 @@ further. - Exiting the tests abruptly maybe leave some docker containers running. Use `docker ps` to find and `docker kill` any containers that may still be running. +### Tests failing locally but not in CI -### Port conflict on 50052 - -If there is a port conflict with an existing process on the local machine then the default port `50052` can be -overridden using `APM_LIBRARY_SERVER_PORT`. +A cause for this can be that the Docker image containing the APM library is cached locally with an older version of the +library. Deleting the image will force a rebuild which will resolve the issue. +```sh +docker image rm -test-library +``` ### Disable build kit @@ -241,16 +179,15 @@ are being produced then likely build kit has to be disabled. To do that open the Docker UI > Docker Engine. Change `buildkit: true` to `buildkit: false` and restart Docker. - -### Tests failing locally but not in CI - -A cause for this can be that the Docker image containing the APM library is cached locally with an older version of the -library. Deleting the image will force a rebuild which will resolve the issue. +### Docker Cleanup +If you encounter an excessive number of errors during your workflow, one potential solution is to perform a cleanup of Docker resources. This can help resolve issues related to corrupted containers, dangling images, or unused volumes that might be causing conflicts. ```sh -docker image rm -test-library +docker system prune ``` +**⚠️ Warning:** +Executing `docker system prune` will remove all stopped containers, unused networks, dangling images, and build caches. This action is **irreversible** and may result in the loss of important data. Ensure that you **do not** need any of these resources before proceeding. ## Developing the tests @@ -259,52 +196,54 @@ docker image rm -test-library The Python implementation of the interface `app/python`, when run, provides a specification of the API when run. See the steps below in the HTTP section to run the Python server and view the specification. -## Implementation - ### Shared Interface -#### GRPC - -In order to achieve shared tests, we introduce a shared GRPC interface to the clients. Thus, each client need only implement the GRPC interface server and then these shared tests can be run against the library. The GRPC interface implements common APIs across the clients which provide the building blocks for test cases. - -```proto -service APMClient { - rpc StartSpan(StartSpanArgs) returns (StartSpanReturn) {} - rpc FinishSpan(FinishSpanArgs) returns (FinishSpanReturn) {} - rpc SpanSetMeta(SpanSetMetaArgs) returns (SpanSetMetaReturn) {} - rpc SpanSetMetric(SpanSetMetricArgs) returns (SpanSetMetricReturn) {} - rpc SpanSetError(SpanSetErrorArgs) returns (SpanSetErrorReturn) {} - rpc InjectHeaders(InjectHeadersArgs) returns (InjectHeadersReturn) {} - rpc FlushSpans(FlushSpansArgs) returns (FlushSpansReturn) {} - rpc FlushTraceStats(FlushTraceStatsArgs) returns (FlushTraceStatsReturn) {} - rpc StopTracer(StopTracerArgs) returns (StopTracerReturn) {} -} -``` +To view the available HTTP endpoints , follow these steps: +Note: These are based off of the Python tracer's http server which should be held as the standard example interface across implementations. -#### HTTP -An HTTP interface can be used instead of the GRPC. To view the interface run +1. `./utils/scripts/parametric/run_reference_http.sh` +2. Navigate to http://localhost:8000/docs in your web browser to access the documentation. +3. You can download the OpenAPI schema from http://localhost:8000/openapi.json. This schema can be imported into tools like [Postman](https://learning.postman.com/docs/integrations/available-integrations/working-with-openAPI/) or other API clients to facilitate development and testing. -``` -PORT=8000 ./utils/scripts/parametric/run_reference_http.sh +Not all endpoint implementations per language are up to spec with regards to their parameters and return values. To view endpoints that are not up to spec, see the [feature parity board](https://feature-parity.us1.prod.dog/#/?runDateFilter=7d&feature=339) + +### Architecture: How System-tests work + +Below is an overview of how the testing architecture is structured: + +- Shared Tests in Python: We write shared test cases using Python's pytest framework. These tests are designed to be generic and interact with the tracers through an HTTP interface. +- [HTTP Servers in Docker](#http-server-implementations): For each language tracer, we build and run an HTTP server within a Docker container. These servers expose the required endpoints defined in the OpenAPI schema and handle the tracer-specific logic. +- [Test Agent](https://github.com/DataDog/dd-apm-test-agent/) in Docker: We start a test agent in a separate Docker container. This agent collects data (such as spans and traces) submitted by the HTTP servers. It serves as a centralized point for aggregating and accessing test data. +- Test Execution: The Python test cases use a [HTTP client](/utils/parametric/_library_client.py) to communicate with the servers. The servers generate data based on the interactions, which is then sent to the test agent. The tests can query the test agent to retrieve data (often traces) and perform assertions to verify correct behavior. + +An example of how to get a span from the test agent: +```python +span = find_only_span(test_agent.wait_for_num_traces(1)) ``` -and navigate to http://localhost:8000/docs. The OpenAPI schema can be downloaded at -http://localhost:8000/openapi.json. The schema can be imported -into [Postman](https://learning.postman.com/docs/integrations/available-integrations/working-with-openAPI/) or -other tooling to assist in development. +This architecture allows us to ensure that all tracers conform to the same interface and behavior, making it easier to maintain consistency across different languages and implementations. +#### Http Server Implementations -### Architecture +The http server implementations for each tracer can be found at the following locations: +*Note:* For some languages there is both an Otel and a Datadog server. This is simply to separate the available Otel endpoints from the available Datadog endpoints that can be hit by the client. If a language only has a single server, then both endpoints for Otel and Datadog exist there. -- Shared tests are written in Python (pytest). -- GRPC/HTTP servers for each language are built and run in docker containers. -- [test agent](https://github.com/DataDog/dd-apm-test-agent/) is started in a container to collect the data from the GRPC servers. +* [Python](/utils/build/docker/python/parametric/apm_test_client/server.py) +* [Ruby](/utils/build/docker/ruby/parametric/server.rb) +* [Php](/utils/build/docker/php/parametric/server.php) +* [Nodejs](/utils/build/docker/nodejs/parametric/server.js) +* [Java Datadog](/utils/build/docker/java/parametric/src/main/java/com/datadoghq/trace/opentracing/controller/OpenTracingController.java) +* [Java Otel](/utils/build/docker/java/parametric/src/main/java/com/datadoghq/trace/opentelemetry/controller/OpenTelemetryController.java) +* [Dotnet Datadog](/utils/build/docker/dotnet/parametric/Endpoints/ApmTestApi.cs) +* [Dotnet Otel](/utils/build/docker/dotnet/parametric/Endpoints/ApmTestApiOtel.cs) +* [Go Datadog](/utils/build/docker/golang/parametric/main.go) +* [Go Otel](/utils/build/docker/golang/parametric/otel.go) -Test cases are written in Python and target the shared GRPC interface. The tests use a GRPC client to query the servers and the servers generate the data which is submitted to the test agent. Test cases can then query the data from the test agent to perform assertions. +![image](https://github.com/user-attachments/assets/fc144fc1-95aa-4d50-97c5-cda8fdbcefef) -image +![image](https://github.com/user-attachments/assets/bb577aa2-b373-4468-b383-8394507309cc) [1]: https://github.com/DataDog/dd-trace-cpp [2]: https://docs.pytest.org/en/6.2.x/usage.html#specifying-tests-selecting-tests diff --git a/docs/scenarios/parametric_contributing.md b/docs/scenarios/parametric_contributing.md new file mode 100644 index 00000000000..012b22c0e3d --- /dev/null +++ b/docs/scenarios/parametric_contributing.md @@ -0,0 +1,68 @@ +# Contributing to Parametric System-tests + +Note: a more in-depth overview of parametric system-tests can be found in [parametric.md](parametric.md). + +**MUST:** Acquaint yourself with [how system tests work](parametric.md#architecture-how-system-tests-work) before proceeding. + +## Use cases + +Let's figure out if your feature is a good candidate to be tested with parametric system-tests. + +System-tests in general are great for assuring uniform behavior between different dd-trace repos (tracing, ASM, DI, profiling, etc.). There are two types of system-tests, [end-to-end](/docs/README.md) and [parametric](/docs/scenarios/parametric.md). + +Parametric tests in the Datadog system test repository validate the behavior of APM Client Libraries by interacting only with their public interfaces. These tests ensure the telemetry generated (spans, metrics, instrumentation telemetry) is consistent and accurate when libraries handle different input parameters (e.g., calling a Tracer's startSpan method with a specific type) and configurations (e.g., sampling rates, distributed tracing header formats, remote settings). They run against web applications written in Ruby, Java, Go, Python, PHP, Node.js, C++, and .NET, which expose endpoints simulating real-world ddtrace usage. The generated telemetry is sent to a Datadog agent, queried, and verified by system tests to confirm proper library functionality across scenarios. + +If your usage does not require different parameter values, then [end-to-end system-tests](/docs/README.md) should be used as they will achieve the same level of behavior uniformity verification and test the feature on real world use cases, catching more issues. End-to-end tests are also what should be used for verify behavior between tracer integrations. +For more on the differences between end-to-end and parametric tests, see [here](/docs/scenarios/README.md#scenarios) +System-tests are **not** for testing internal or niche library behavior. Unit tests are a better fit for that case. + +## Getting set up + +We usually add new system tests when validating a new feature. To begin, set up the system-tests repo to run with a version of the library that has already implemented the feature you'd like to test (published or on a branch). +Follow [Binaries Documentation](../execute/binaries.md) for your particular tracer language to set this up. + +[Verify that you can run some (any) parametric tests with your custom tracer](parametric.md#running-the-tests). Make sure some pass — no need to run the whole suite (you can stop the tests from running with `ctrl+c`). If you have any issues, checkout the [debugging section](parametric.md#debugging) to troubleshoot. + +## Writing the tests + +Now that we're all setup with a working test suite and a tracer with the implemented feature, we can begin writing the new tests. + +**MUST:** If you haven't yet, please acquaint yourself with [how system tests work](parametric.md#architecture-how-system-tests-work) before proceeding and reference it throughout this section. + +Before writing a new test, check the [existing tests](/tests/parametric) to see if you can use the same methods or endpoints for similar scenarios; in many cases, new endpoints do not need to be added. + +For a list of client methods that already exist, refer to `class APMLibrary` in the [_library_client.py](/utils/parametric/_library_client.py). If you're wondering what the methods do, you can take at look at the respective endpoints they're calling in that same file in `class APMLibraryClient`. + +The endpoints (where the actual tracer code runs) are defined in the Http Server implementations per tracer [listed here](parametric.md#http-server-implementations). Click on the one for your language to take a look at the endpoints. In some cases you may need to just slightly modify an endpoint rather than add a new one. + +### If you need to add additional endpoints to test your new feature + +*Note:* please refer to the [architecture section](parametric.md#architecture-how-system-tests-work) if you're confused throughout this process. + +Then we need to do the following: + +* Determine what you want the endpoint to be called and what you need it to do, and add it to your tracer's http server. + +*Note:* If adding a new endpoint please let a Python tracer implementer know so they can add it as well [see](parametric.md#shared-interface) +*Note*: Only add new endpoints that operate on the public API and execute ONE operation. Endpoints that execute complex operations or validate tracer internals will not be accepted. +* In [_library_client.py](/utils/parametric/_library_client.py) Add both the endpoint call in `class APMLibraryClient` and the method that invokes it in `class APMLibrary`. Use other implementations for reference. + +* Ok we now have our new method! Use it in the tests you write using the [below section](#if-the-methods-you-need-to-run-your-tests-are-already-written) + +### If the methods you need to run your tests are already written + +If it makes sense to add your tests to a file that already exists, great! Otherwise make a new test file in `tests/parametric`. + +Next copy the testing code you want to use as a base/guideline (usually the class (if using a new file) and one of the test methods in it). + +Then: + +* [Change the name of the feature annotation it'll fit under for the feature parity board](/docs/edit/features.md) (Not always needed e.g. `@features.datadog_headers_propagation` is used for all the propagation features) +* Change the class and method name to fit what you're testing. +* [Change your tracer's respective manifest.yml file](/docs/edit/manifest.md) or else the script won't know to run your new test. If you're confused at how to do this properly, search for the file you copied the test from in the manifest file and see how it's specified, you can probably copy that for your new file (make sure the path is the same). +For the version value, to make sure your test runs, specify the current release your tracer is on. This is the minimum value that the script will run your test with. If you make it too high, the script will skip your test. +* Write the test pulling from examples of other tests written. Remember you're almost always follwing the pattern of making spans, getting them from the trace_agent, and then verifying values on them. + +**Finally:** +[Try running your test!](parametric.md#running-the-tests) +If you have an issue, checkout the [debugging section](parametric.md#debugging) to troubleshoot. diff --git a/docs/weblog/README.md b/docs/weblog/README.md index d06f0983532..ffe38e60e5c 100644 --- a/docs/weblog/README.md +++ b/docs/weblog/README.md @@ -1,12 +1,13 @@ # Weblog A weblog is a web app that system uses to test the library. It mimics what would be a real instrumented HTTP application. A weblog app is required for each platform that the system tests will test. The weblog must implement a number of different endpoints. +Weblog implementations are located in `utils/docker/`. > Note: a separate document describes [GraphQL Weblog](./graphql_weblog.md). ## Disclaimer -This document describes endpoints implemented on weblog. Though, it's not a complete description, and can contains mistakes. The source of truth are the test itself. If a weblog endpoint passes system tests, then you can consider it as ok. And if it does not passes it, then you must correct it, even if it's in line with this document. +This document describes endpoints implemented on weblog. Though, it's not a complete description, and can contain mistakes. The source of truth are the test itself. If a weblog endpoint passes system tests, then you can consider it as ok. And if it does not passes it, then you must correct it, even if it's in line with this document. **You are strongly encouraged to help others by submitting corrections when you notice issues with this document.** @@ -85,6 +86,27 @@ The following text may be written to the body of the response: Hello world!\n ``` +### GET /api_security/sampling/%i + +This endpoint is used for API security sampling and must accept a parameter `i` as an integer. + +The response body may contain the following text: + +``` +Hello!\n +``` + +### GET /api_security_sampling/%i + +This endpoint is used in conjunction with `GET /api_security/sampling/%i` for API security sampling and must accept a parameter `i` as an integer. + +The response body may contain the following text: + +``` +OK\n +``` + + ### GET /spans The endpoint may accept two query string parameters: @@ -175,6 +197,22 @@ must set the appropriate tag in the span to `tainted_value` and return a respons The goal is to be able to easily test if a request was blocked before reaching the server code or after by looking at the span and also test security rules on reponse status code or response header content. +### GET /iast/insecure-cookie/test_secure + +This endpoint should set at least one cookie with all security flags (Secure, HttpOnly, SameSite=Strict) to prevent any vulnerabilities from being detected. + +### GET /iast/insecure-cookie/test_insecure + +This endpoint should set a cookie with all security flags except Secure, to detect only the INSECURE_COOKIE vulnerability. + +### POST /iast/insecure-cookie/custom_cookie + +This endpoint should set a cookie with the name and value coming from the request body (using the cookieName and cookieValue properties), with all security flags except Secure, to detect only the INSECURE_COOKIE vulnerability. + +### GET /iast/insecure-cookie/test_empty_cookie + +This endpoint should set a cookie with empty cookie value without Secure flag, INSECURE_COOKIE vulnerability shouldn't be detected. + ### GET /iast/insecure_hashing/deduplicate Parameterless endpoint. This endpoint contains a vulnerable souce code line (weak hash) in a loop with at least two iterations. @@ -197,6 +235,46 @@ The endpoint executes a unique operation of String hashing with unsecure MD5 alg Parameterless endpoint. This endpoint contains a hardcoded secret. The declaration of the hardcoded secret should be sufficient to trigger the vulnerability, so returning it in the response is optional. +### GET /iast/no-httponly-cookie/test_secure + +This endpoint should set at least one cookie with all security flags (Secure, HttpOnly, SameSite=Strict) to prevent any vulnerabilities from being detected. + +### GET /iast/no-httponly-cookie/test_insecure + +This endpoint should set a cookie with all security flags except HttpOnly, to detect only the NO_HTTPONLY_COOKIE vulnerability. + +### GET /iast/no-httponly-cookie/test_empty_cookie + +This endpoint should set a cookie with empty cookie value without HttpOnly flag, NO_HTTPONLY_COOKIE vulnerability shouldn't be detected. + +### POST /iast/no-httponly-cookie/custom_cookie + +This endpoint should set a cookie with the name and value coming from the request body (using the cookieName and cookieValue properties), with all security flags except HttpOnly, to detect only the NO_HTTPONLY_COOKIE vulnerability. + +### GET /iast/no-samesite-cookie/test_secure + +This endpoint should set at least one cookie with all security flags (Secure, HttpOnly, SameSite=Strict) to prevent any vulnerabilities from being detected. + +### GET /iast/no-samesite-cookie/test_insecure + +This endpoint should set a cookie with all security flags except SameSite=Strict, to detect only the NO_SAMESITE_COOKIE vulnerability. + +### GET /iast/no-samesite-cookie/test_empty_cookie + +This endpoint should set a cookie with empty cookie value without SameSite=Strict flag, NO_SAMESITE_COOKIE vulnerability shouldn't be detected. + +### POST /iast/no-samesite-cookie/custom_cookie + +This endpoint should set a cookie with the name and value coming from the request body (using the cookieName and cookieValue properties), with all security flags except SameSite=Strict, to detect only the NO_SAMESITE_COOKIE vulnerability. + +### GET /iast/header_injection/reflected/exclusion + +This endpoint should set the header whose name comes in the `reflected` field of the query string, with the reflected value of another header whose name comes in the `origin` field of the query string. + +### GET /iast/header_injection/reflected/no-exclusion + +Same behaviour as `/iast/header_injection/reflected/exclusion` but with separate specific cases to obtain a different vulnerability location to avoid deduplication. + ### \[GET, POST\] /iast/source/* This group of endpoints should trigger vulnerabilities detected by IAST with untrusted data coming from certain sources. The used vulnerability is irrelevant. It could be a command injection, SQL injection, or something else. @@ -233,7 +311,7 @@ A GET request using a cookie with name `table` and any value. The value must be #### GET /iast/source/cookiename/test -A GET request using a cookie with name `user` and any value. The name must be used in the vulnerability. +A GET request using a cookie with name `table` and any value. The name must be used in the vulnerability. #### POST /iast/source/multipart/test A multipart request uploading a file (with a file name). @@ -246,7 +324,9 @@ A POST request which will receive the following JSON body: {"name": "table", "value": "user"} ``` -Where the value for `value` must be used in the vulnerability. +#### GET /iast/source/sql/test + +An empty GET request that will execute two database queries, one to get a username and another to do a vulnerable SELECT using the obtained username. ### GET /make_distant_call @@ -295,7 +375,142 @@ be returned. Expected query params: - `integration`: Name of messaging tech - - Possible Values: `kafka`, `rabbitmq`, `sqs` + - Possible Values: `kafka`, `rabbitmq`, `sqs`, `kinesis`, `sns` + - `message`: Specific message to produce and consume + - `topic`: Name of messaging topic (if using `integration=sns`) + - `queue`: Name of messaging queue (if using `integration=kafka|rabbitmq|sqs|sns (for sns->sqs tests)`) + - `stream`: Name of messaging stream (if using `integration=kinesis`) + - `exchange`: Name of messaging exchange (if using `integration=rabbitmq`) + - `routingKey`: Name of message routing key (if using `integration=rabbitmq`) + - `timeout`: Timeout in seconds + +### GET /kafka/produce + +This endpoint triggers Kafka producer calls. + +Expected query params: + - `topic`: Name of the Kafka topic to which the message will be produced. + +### GET /kafka/consume + +This endpoint triggers Kafka consumer calls. + +Expected query params: + - `topic`: Name of the Kafka topic from which the message will be consumed. + - `timeout`: Timeout in seconds for the consumer operation. + +### GET /sqs/produce + +This endpoint triggers SQS producer calls. + +Expected query params: + - `queue`: Name of the SQS queue to which the message will be produced. + - `message`: Specific message to be produced to the SQS queue. + +### GET /sqs/consume + +This endpoint triggers SQS consumer calls. + +Expected query params: + - `queue`: Name of the SQS queue from which the message will be consumed. + - `timeout`: Timeout in seconds for the consumer operation. + - `message`: Specific message to be consumed from the SQS queue. + +### GET /sns/produce + +This endpoint triggers SNS producer calls. + +Expected query params: + - `queue`: Name of the SQS queue associated with the SNS topic for message production. + - `topic`: Name of the SNS topic to which the message will be produced. + - `message`: Specific message to be produced to the SNS topic. + +### GET /sns/consume + +This endpoint triggers SNS consumer calls. + +Expected query params: + - `queue`: Name of the SQS queue associated with the SNS topic for message consumption. + - `timeout`: Timeout in seconds for the consumer operation. + - `message`: Specific message to be consumed from the SNS topic. + +### GET /kinesis/produce + +This endpoint triggers Kinesis producer calls. + +Expected query params: + - `stream`: Name of the Kinesis stream to which the message will be produced. + - `timeout`: Timeout in seconds for the producer operation. + - `message`: Specific message to be produced to the Kinesis stream. + +### GET /kinesis/consume + +This endpoint triggers Kinesis consumer calls. + +Expected query params: + - `stream`: Name of the Kinesis stream from which the message will be consumed. + - `timeout`: Timeout in seconds for the consumer operation. + - `message`: Specific message to be consumed from the Kinesis stream. + +### GET /rabbitmq/produce + +This endpoint triggers RabbitMQ producer calls. + +Expected query params: + - `queue`: Name of the RabbitMQ queue to which the message will be produced. + - `exchange`: Name of the RabbitMQ exchange to which the message will be produced. + - `routing_key`: Name of the RabbitMQ routing key for message production. + +### GET /rabbitmq/consume + +This endpoint triggers RabbitMQ consumer calls. + +Expected query params: + - `queue`: Name of the RabbitMQ queue from which the message will be consumed. + - `exchange`: Name of the RabbitMQ exchange from which the message will be consumed. + - `routing_key`: Name of the RabbitMQ routing key for message consumption. + - `timeout`: Timeout in seconds for the consumer operation. + +### GET /dsm/manual/produce + +This endpoint sets a DSM produce operation manual API checkpoint. A 200 response with "ok" is returned along with the +base64 encoded context: `dd-pathway-ctx-base64`, which is returned within the response headers. Otherwise, error +messages will be returned. + +Expected query params: + - `type`: Type of DSM checkpoint, typically the system name such as 'kafka' + - `target`: Target queue name + +### GET /dsm/manual/produce_with_thread + +This endpoint sets a DSM produce operation manual API checkpoint, doing so within another thread to ensure DSM context +API works cross-thread. A 200 response with "ok" is returned along with the base64 encoded context: +`dd-pathway-ctx-base64`, which is returned within the response headers. Otherwise, error messages will be returned. + +Expected query params: + - `type`: Type of DSM checkpoint, typically the system name such as 'kafka' + - `target`: Target queue name + +### GET /dsm/manual/consume + +This endpoint sets a DSM consume operation manual API checkpoint. The DSM base64 encoded context: `dd-pathway-ctx-base64` +should be included in the request headers under the `_datadog` header tag as a JSON formatted string. A 200 response with +text "ok" is returned upon success. Otherwise, error messages will be returned. + +Expected query params: + - `type`: Type of DSM checkpoint, typically the system name such as 'kafka' + - `target`: Target queue name + +### GET /dsm/manual/consume_with_thread + +This endpoint sets a DSM consume operation manual API checkpoint, doing so within another thread to ensure DSM context +API works cross-thread. The DSM base64 encoded context `dd-pathway-ctx-base64` should be included in the request headers +under the `_datadog` header tag as a JSON formatted string. A 200 response with text "ok" is returned upon success. +Otherwise, error messages will be returned. + +Expected query params: + - `type`: Type of DSM checkpoint, typically the system name such as 'kafka' + - `target`: Target queue name ### GET /user_login_success_event @@ -328,6 +543,23 @@ By default, the generated event has the following specification: Values can be changed with the query params called `event_name`. +### GET '/inferred-proxy/span-creation' + +This endpoint is supposed to be hit with the necessary headers that are used to create inferred proxy +spans for routers such as AWS API Gateway. Not including the headers means a span will not be created by the tracer +if the feature exists. + +The endpoint supports the following query parameters: + - `status_code`: str containing status code to used in API response + +The headers necessary to create a span with example values: + `x-dd-proxy-request-time-ms`: start time in milliseconds + `x-dd-proxy-path`: "/api/data", + `x-dd-proxy-httpmethod`: "GET", + `x-dd-proxy-domain-name`: "system-tests-api-gateway.com", + `x-dd-proxy-stage`: "staging", + `x-dd-proxy`: "aws-apigateway", + ### GET /users This endpoint calls the appsec blocking SDK functions used for blocking users. If the expected parameter matches one of @@ -380,37 +612,28 @@ Body fields accepted in POST method: - `password`: password for the user. It also supports HTTP authentication by using GET method and the authorization header. -Additionally both methods support the following query parameters to use the sdk functions along with the authentication framework: +Additionally, both methods support the following query parameters to use the sdk functions along with the authentication framework: - `sdk_event`: login event type: `success` or `failure`. - `sdk_user`: user id to be used in the sdk call. - `sdk_mail`: user's mail to be used in the sdk call. -- `sdk_user_exists`: `true` of `false` to indicate wether the current user exists and populate the corresponding tag. - -### GET /debugger -These endpoints are used for the Live Debugger tests in `test_debugger.py`. Currently, they are placeholders but will eventually be used to create and test different probe definitions. - -#### GET /debugger/log -This endpoint will be used to validate the log probe. +- `sdk_user_exists`: `true` of `false` to indicate whether the current user exists and populate the corresponding tag. -#### GET /debugger/metric -This endpoint will be used to validate the metric probe. - -#### GET /debugger/span -This endpoint will be used to validate the span probe. - -#### GET /debugger/span-decoration -This endpoint will be used to validate the span decoration probe. +### \[POST\] /signup +This endpoint is used to create a new user. Do not keep the user in memory for later use, only call the framework method to pretend to do so. +Body fields accepted in POST method: +- `username`: the login name for the user. +- `password`: password for the user. -The following query parameters are required for each endpoint: -- `arg`: This is a parameter that can take any string as an argument. -- `intArg`: This is a parameter that can take any integer as an argument. +Additionally, the method supports the following query parameters to use the sdk functions along with the authentication framework: +- `sdk_event`: login event type: `signup`. +- `sdk_user`: user id to be used in the sdk call. +- `sdk_mail`: user's mail to be used in the sdk call. -#### GET /debugger/pii -This endpoint will be used to validate debugger pii redaction feature. +### GET /debugger/* +These endpoints are used for the `Dynamic Instrumentation` tests. -#### GET /expression -#### GET /expression/exception -These endpoints will be used to validate debugger expression language feature. +#### GET /exceptionreplay/* +These endpoints will be used for `Exception Replay` tests. ### GET /createextraservice should rename the trace service, creating a "fake" service @@ -502,5 +725,141 @@ This endpoint is used to validate DSM context extraction works correctly when pr This endpoint is used to test ASM Standalone propagation, by calling `/returnheaders` and returning it's value (the headers received) to inspect them, looking for distributed tracing propagation headers. +### \[GET\] /vulnerablerequestdownstream + +Similar to `/requestdownstream`. This is used to test standalone IAST downstream propagation. It should call `/returnheaders` and returning return the resulting json data structure from `/returnheaders` in its response. + ### \[GET,POST\] /returnheaders This endpoint returns the headers received in order to be able to assert about distributed tracing propagation headers + +### \[GET\] /stats-unique +The endpoint must accept a query string parameter `code`, which should be an integer. This parameter will be the status code of the response message, default to 200 OK. +This endpoint is used for client-stats tests to provide a separate "resource" via the endpoint path `stats-unique` to disambiguate those tests from other +stats generating tests. + +### GET /healthcheck + +Returns a JSON dict, with those values : + +```js +{ + "status": "ok", + "library": { + "language": "", // one of cpp, dotnet, golang, java, nodejs, php, python, ruby + "version": "1.2.3" // version of the library + } + } +``` + +### \[GET,POST\] /rasp/shi + +This endpoint is used to test for shell injection attacks, consequently it must call a shell command by using a function or method which results in an actual shell being launched (e.g. /bin/sh). The chosen operation must be injected with the `GET` or `POST` parameter. + +Query parameters and body fields required in the `GET` and `POST` method: +- `list_dir`: containing the string to inject on the shell command. + +The endpoint should support the following content types in the `POST` method: +- `application/x-www-form-urlencoded` +- `application/xml` +- `application/json` + +The chosen operation must use the file as provided, without any alterations, e.g.: +``` +system("ls $list_dir"); +``` + +Examples: +- `GET`: `/rasp/shi?list_dir=$(cat /etc/passwd 1>&2 ; echo .) +- `POST`: `{"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}` + +### \[GET,POST\] /rasp/cmdi + +This endpoint is used to test for command injection attacks by executing a command without launching a shell. +The chosen operation must be injected with the `GET` or `POST` parameter. + +Query parameters and body fields required in the `GET` and `POST` method: +- `command`: containing string or an array of strings to be executed as a command. + +The endpoint should support the following content types in the `POST` method: +- `application/x-www-form-urlencoded` +- `application/xml` +- `application/json` + +The chosen operation must use the file as provided, without any alterations, e.g.: +``` +system("$command"); +``` + +Examples: +- `GET`: `/rasp/cmdi?command=/usr/bin/touch /tmp/passwd +- `POST`: `{"command": ["/usr/bin/touch", "/tmp/passwd"]}` + +### \[GET\] /set_cookie + +This endpoint get a `name` and a `value` form the query string, and adds a header `Set-Cookie` with `{name}={value}` as header value in the HTTP response + +### \[GET\] /session/new + +This endpoint is the initial endpoint used to test session fingerprints, consequently it must initialize a new session and the web client should be able to deal with the persistence mechanism (e.g. cookies). + +Returns the identifier of the created session id. Example : + +```text +c377db41-b664-4e30-af57-5df2e803bec7 +``` + +Examples: +- `GET`: `/session/new` + +### \[GET\] /session/user + +Once a session has been established, a new call to `/session/user` must be made in order to generate a session fingerprint with the session id provided by the web client (e.g. cookie) and the user id provided as a parameter. + +Query parameters required in the `GET` method: +- `sdk_user`: user id used in the WAF login event triggered during the execution of the request. + +Examples: +- `GET`: `/session/user?sdk_user=sdkUser` + +### \[GET\] /mock_s3/put_object + +This endpoint is used to test the s3 integration. It creates a bucket if +necessary based on the `bucket` query parameter and puts an object at the `key` +query parameter. The body of the object is just the bytes of the key, encoded +with utf-8. Returns a result object with an `object` JSON object field containing the +`e_tag` field with the ETag of the uploaded object. The `e_tag` field has any +extra double-quotes stripped (accounting for a quirk in the boto3 library). + +Examples: +- `GET`: `/mock_s3/put_object?bucket=somebucket&key=somekey` + + +### \[GET\] /mock_s3/copy_object + +This endpoint is used to test the s3 integration. It creates a bucket if +necessary based on the `original_bucket` query parameter and puts an object at +the `original_key` query parameter. The body of the object is just the bytes of +the key, encoded with utf-8. The method then creates another `bucket` if +necessary and copies the object into the `key` location. Returns a result +object with an `object` JSON object field containing the `e_tag` field with the +ETag of the copied object. The `e_tag` field has any extra double-quotes +stripped (accounting for a quirk in the boto3 library). + +Examples: +- `GET`: `/mock_s3/copy_object?original_bucket=somebucket&original_key=somekey&bucket=someotherbucket&key=someotherkey` + + +### \[GET\] /mock_s3/multipart_upload + +This endpoint is used to test the s3 integration. It creates a bucket if +necessary based on the `bucket` query parameter and puts an object at the `key` +query parameter. The body of the object is just the bytes of the key, encoded +with utf-8, duplicated enough times to make two multipart uploads. Returns a +result object with an `object` JSON object field containing the `e_tag` field +with the ETag of the uploaded object returned by the final +CompleteMultipartUpload call. The `e_tag` field has any extra double-quotes +stripped (accounting for a quirk in the boto3 library). + +Examples: +- `GET`: `/mock_s3/multipart_upload?bucket=somebucket&key=somekey` + diff --git a/flake.nix b/flake.nix index 8bc4a6717af..25b929c5e40 100644 --- a/flake.nix +++ b/flake.nix @@ -54,7 +54,7 @@ treefmt.config.build.wrapper python - + pkgs.ruff ]; @@ -79,3 +79,5 @@ }; })); } + +# todo Merge with upstream changes \ No newline at end of file diff --git a/format.sh b/format.sh index f4a0ccd9271..0bc61c89127 100755 --- a/format.sh +++ b/format.sh @@ -46,6 +46,64 @@ fi # shellcheck source=/dev/null source venv/bin/activate -pylint utils # pylint does not have a fix mode +echo "Running mypy type checks..." +if ! mypy --config pyproject.toml; then + echo "Mypy type checks failed. Please fix the errors above. 💥 💔 💥" + exit 1 +fi + +echo "Running ruff checks..." +if ! which ruff > /dev/null; then + echo "ruff is not installed, installing it (ETA 5s)" + ./build.sh -i runner > /dev/null +fi + +echo "Running ruff formatter..." +if [ "$COMMAND" == "fix" ]; then + ruff format +else + ruff format --check --diff +fi + +if [ "$COMMAND" == "fix" ]; then + ruff_args="--fix" +else + ruff_args="" +fi + +if ! ruff check $ruff_args; then + echo "ruff checks failed. Please fix the errors above. 💥 💔 💥" + exit 1 +fi + +echo "Checking trailing whitespaces..." +INCLUDE_PATTERN='.*\.(md|yml|yaml|sh|cs|Dockerfile|java|sql|ts|js|php)$' +EXCLUDE_PATTERN='utils/build/virtual_machine' +# Check all files tracked by git, and matching include/exclude patterns +FILES="$(git ls-files | grep -v -E "$EXCLUDE_PATTERN" | grep -E "$INCLUDE_PATTERN" | while read f ; do grep -l ' $' "$f" || true ; done)" + +# shim for sed -i on GNU sed (Linux) and BSD sed (macOS) +_sed_i() { + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' -r "$@" + else + sed -i "$@" + fi +} + +if [ "$COMMAND" == "fix" ]; then + echo "$FILES" | while read file ; do + if [[ -n "$file" ]]; then + echo "Fixing $file" + _sed_i 's/ *$//g' "$file" + fi + done +else + if [ -n "$FILES" ]; then + echo "Some trailing white spaces has been found, please fix them 💥 💔 💥" + echo "$FILES" + exit 1 + fi +fi -echo "All good, the system-tests CI will be happy! ✨ 🍰 ✨" \ No newline at end of file +echo "All good, the system-tests CI will be happy! ✨ 🍰 ✨" diff --git a/lib-injection/build/build_lib_injection_images.sh b/lib-injection/build/build_lib_injection_images.sh index 10c3f6d6751..5e07fe953e5 100755 --- a/lib-injection/build/build_lib_injection_images.sh +++ b/lib-injection/build/build_lib_injection_images.sh @@ -2,19 +2,24 @@ set -e export DOCKER_IMAGE_WEBLOG_TAG=latest -export BUILDX_PLATFORMS=linux/arm64/v8,linux/amd64 +export BUILDX_PLATFORMS=linux/arm64,linux/amd64 declare -A variants variants=(["dd-lib-dotnet-init-test-app"]="dotnet" ["sample-app"]="nodejs" ["dd-lib-python-init-test-django"]="python" ["dd-lib-python-init-test-django-gunicorn"]="python" + ["dd-lib-python-init-test-django-gunicorn-alpine"]="python" + ["dd-lib-python-init-test-django-preinstalled"]="python" + ["dd-lib-python-init-test-django-unsupported-package-force"]="python" ["dd-lib-python-init-test-django-uvicorn"]="python" + ["dd-lib-python-init-test-protobuf-old"]="python" + ["dd-lib-java-init-test-app"]="java" + ["dd-djm-spark-test-app"]="java" ["dd-lib-ruby-init-test-rails"]="ruby" ["dd-lib-ruby-init-test-rails-bundle-deploy"]="ruby" ["dd-lib-ruby-init-test-rails-conflict"]="ruby" ["dd-lib-ruby-init-test-rails-explicit"]="ruby" ["dd-lib-ruby-init-test-rails-gemsrb"]="ruby" - ["dd-lib-java-init-test-app"]="java" ) docker buildx create --name multiarch --driver docker-container --use @@ -22,6 +27,5 @@ for variant in "${!variants[@]}"; do language="${variants[$variant]}" echo "Building $variant - $language"; echo "$(pwd)" - ./lib-injection/build/build_lib_injection_weblog.sh -w $variant -l $language --push-tag ghcr.io/datadog/system-tests/$variant:$DOCKER_IMAGE_WEBLOG_TAG - + ./lib-injection/build/build_lib_injection_weblog.sh -w $variant -l $language --push-tag ghcr.io/datadog/system-tests/$variant:$DOCKER_IMAGE_WEBLOG_TAG --docker-platform $BUILDX_PLATFORMS done \ No newline at end of file diff --git a/lib-injection/build/build_lib_injection_weblog.sh b/lib-injection/build/build_lib_injection_weblog.sh index 6f712b80a0f..b0ced8e566e 100755 --- a/lib-injection/build/build_lib_injection_weblog.sh +++ b/lib-injection/build/build_lib_injection_weblog.sh @@ -54,12 +54,15 @@ if [[ $TEST_LIBRARY == "ruby" ]]; then cp $WEBLOG_FOLDER/../.dockerignore $WEBLOG_FOLDER/ fi -ARCH=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/') +if [[ -z "${DOCKER_PLATFORM:-}" ]]; then -case $ARCH in - arm64|aarch64) DOCKER_PLATFORM_ARGS="${DOCKER_PLATFORM:-"--platform linux/arm64/v8"}";; - *) DOCKER_PLATFORM_ARGS="${DOCKER_PLATFORM:-"--platform linux/amd64"}";; -esac + ARCH=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/') + + case $ARCH in + arm64|aarch64) DOCKER_PLATFORM_ARGS="${DOCKER_PLATFORM:-"--platform linux/arm64/v8"}";; + *) DOCKER_PLATFORM_ARGS="${DOCKER_PLATFORM:-"--platform linux/amd64"}";; + esac +fi echo "Building docker weblog image using variant [${WEBLOG_VARIANT}] and library [${TEST_LIBRARY}]" @@ -67,7 +70,6 @@ CURRENT_DIR=$(pwd) cd $WEBLOG_FOLDER if [ -n "${PUSH_TAG+set}" ]; then - echo $GH_TOKEN | docker login ghcr.io -u publisher --password-stdin docker buildx build ${DOCKER_PLATFORM} -t ${PUSH_TAG} . --push else docker build ${DOCKER_PLATFORM} -t weblog-injection:latest . diff --git a/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/Dockerfile b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/Dockerfile new file mode 100644 index 00000000000..f5fcda1a2e7 --- /dev/null +++ b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/Dockerfile @@ -0,0 +1,15 @@ +FROM mcr.microsoft.com/dotnet/aspnet:2.1-stretch-slim AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:7.0.100 AS build +WORKDIR /app +COPY . . +RUN dotnet publish -c Release -o /publish + +FROM base AS final +WORKDIR /app +EXPOSE 18080 +ENV ASPNETCORE_URLS=http://+:18080 +COPY --from=build /publish . + +ENTRYPOINT ["dotnet", "MinimalWebApp.dll"] \ No newline at end of file diff --git a/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/MinimalWebApp.csproj b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/MinimalWebApp.csproj new file mode 100644 index 00000000000..5d344418494 --- /dev/null +++ b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/MinimalWebApp.csproj @@ -0,0 +1,12 @@ + + + + netcoreapp2.1 + MinimalWebApp + + + + + + + diff --git a/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/Program.cs b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/Program.cs new file mode 100644 index 00000000000..568d316d0f7 --- /dev/null +++ b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/Program.cs @@ -0,0 +1,21 @@ +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; + +namespace MinimalWebApp +{ + public class Program + { + public static void Main(string[] args) + { + WebHost.CreateDefaultBuilder(args) + .Configure(app => + { + app.Run(async context => await context.Response.WriteAsync("Hello World!")); + }) + .Build() + .Run(); + } + } +} diff --git a/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/appsettings.json b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/appsettings.json new file mode 100644 index 00000000000..8929653dd9b --- /dev/null +++ b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug" + } + }, + "AllowedHosts": "*" +} diff --git a/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/build.sh b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/build.sh new file mode 100644 index 00000000000..5eb38792fc1 --- /dev/null +++ b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app-unsupported/build.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if [ -z "${BUILDX_PLATFORMS}" ] ; then + BUILDX_PLATFORMS="linux/amd64" +fi + +docker buildx build --platform ${BUILDX_PLATFORMS} --tag ${LIBRARY_INJECTION_TEST_APP_IMAGE} --push . \ No newline at end of file diff --git a/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app/Program.cs b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app/Program.cs index 1760df1d28b..23c84f4f504 100644 --- a/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app/Program.cs +++ b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app/Program.cs @@ -1,6 +1,187 @@ +using System.Diagnostics; + +if (Environment.GetEnvironmentVariable("FORKED") != null) +{ + Thread.Sleep(5_000); // Add a small delay otherwise the telemetry forwarder leaves a zombie process behind + CrashMe(null); + + // Should never get there + Thread.Sleep(Timeout.Infinite); +} + var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); +static string CrashMe(HttpRequest? request) +{ + var thread = new Thread(() => + { + throw new BadImageFormatException("Expected"); + }); + + thread.Start(); + thread.Join(); + + return "Failed to crash"; +} + +static string ForkAndCrash(HttpRequest request) +{ + // Simulate fork + var startInfo = new ProcessStartInfo + { + FileName = Environment.ProcessPath, + Arguments = Environment.CommandLine, + }; + + startInfo.Environment["FORKED"] = "1"; + + var process = Process.Start(startInfo)!; + process.WaitForExit(); + + return $"Process {process.Id} has exited with code {process.ExitCode}"; +} + +static string GetChildPids(HttpRequest request) +{ + var currentPid = Environment.ProcessId; + var childPids = new List(); + + try + { + // Read all the directories in /proc + foreach (var dir in Directory.GetDirectories("/proc")) + { + // If the directory name is a number, it represents a PID + if (int.TryParse(Path.GetFileName(dir), out int pid)) + { + var statusFile = Path.Combine(dir, "status"); + + try + { + // Read the status file to find the PPid line + var lines = File.ReadAllLines(statusFile); + foreach (var line in lines) + { + if (line.StartsWith("PPid:")) + { + var parts = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); + if (parts.Length > 1 && int.TryParse(parts[1], out int ppid) && ppid == currentPid) + { + childPids.Add(pid.ToString()); + } + break; + } + } + } + catch (IOException) + { + // The process may have terminated, just continue + continue; + } + catch (UnauthorizedAccessException) + { + // We may not have permission to read some process information, just continue + continue; + } + } + } + + return string.Join(", ", childPids); + } + catch (Exception ex) + { + return $"Error: {ex.Message}"; + } +} + +static string GetZombies(HttpRequest request) +{ + var zombieProcesses = new List(); + + try + { + // Read all the directories in /proc + foreach (var dir in Directory.GetDirectories("/proc")) + { + // If the directory name is a number, it represents a PID + if (int.TryParse(Path.GetFileName(dir), out int pid)) + { + var statusFile = Path.Combine(dir, "status"); + + try + { + // Read the status file to find the Name, State, and PPid lines + string? name = null; + string? state = null; + string? ppid = null; + + var lines = File.ReadAllLines(statusFile); + foreach (var line in lines) + { + if (line.StartsWith("Name:")) + { + var parts = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); + if (parts.Length > 1) + { + name = parts[1]; + } + } + else if (line.StartsWith("State:")) + { + var parts = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); + if (parts.Length > 1) + { + state = parts[1]; + } + } + else if (line.StartsWith("PPid:")) + { + var parts = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); + if (parts.Length > 1) + { + ppid = parts[1]; + } + } + + if (name != null && state != null && ppid != null) + { + break; + } + } + + // Check if the process state is 'Z' (zombie) + if (state == "Z") + { + zombieProcesses.Add($"{name} (PID: {pid}, PPID: {ppid})"); + } + } + catch (IOException) + { + // The process may have terminated, just continue + continue; + } + catch (UnauthorizedAccessException) + { + // We may not have permission to read some process information, just continue + continue; + } + } + } + + return string.Join(", ", zombieProcesses); + } + catch (Exception ex) + { + return $"Error: {ex.Message}"; + } +} + + app.MapGet("/", () => "Hello World!"); +app.MapGet("/crashme", CrashMe); +app.MapGet("/fork_and_crash", ForkAndCrash); +app.MapGet("/child_pids", GetChildPids); +app.MapGet("/zombies", GetZombies); app.Run(); diff --git a/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app/appsettings.json b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app/appsettings.json index 10f68b8c8b4..8929653dd9b 100644 --- a/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app/appsettings.json +++ b/lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app/appsettings.json @@ -1,8 +1,7 @@ { "Logging": { "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" + "Default": "Debug" } }, "AllowedHosts": "*" diff --git a/lib-injection/build/docker/java/dd-djm-spark-test-app/Dockerfile b/lib-injection/build/docker/java/dd-djm-spark-test-app/Dockerfile new file mode 100644 index 00000000000..96cc099bd53 --- /dev/null +++ b/lib-injection/build/docker/java/dd-djm-spark-test-app/Dockerfile @@ -0,0 +1,11 @@ +FROM apache/spark:3.4.4 + +WORKDIR /opt/spark/work-dir + +USER root +COPY launch.sh /opt/spark/work-dir/launch.sh +RUN chown spark:spark /opt/spark/work-dir/launch.sh +RUN chmod +x /opt/spark/work-dir/launch.sh +USER spark + +CMD ["/opt/spark/work-dir/launch.sh"] diff --git a/lib-injection/build/docker/java/dd-djm-spark-test-app/launch.sh b/lib-injection/build/docker/java/dd-djm-spark-test-app/launch.sh new file mode 100644 index 00000000000..5208dfbae57 --- /dev/null +++ b/lib-injection/build/docker/java/dd-djm-spark-test-app/launch.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +if [ -z "${LIB_INIT_IMAGE}" ]; then + echo "LIB_INIT_IMAGE is not set" + exit 1 +else + echo "LIB_INIT_IMAGE is set to ${LIB_INIT_IMAGE}" +fi + +if [ -z "${AUTO_INJECT_VERSION}" ]; then + echo "AUTO_INJECT_VERSION is not set, default to latest" + AUTO_INJECT_VERSION="latest" # default to latest for now. +else + echo "AUTO_INJECT_VERSION is set to ${AUTO_INJECT_VERSION}" +fi + +# Submit a example spark job with DJM enabled +$SPARK_HOME/bin/spark-submit \ +--class org.apache.spark.examples.SparkPi \ + --master k8s://https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT \ + --conf spark.kubernetes.container.image=apache/spark:3.4.4 \ + --deploy-mode cluster \ + --conf spark.kubernetes.namespace=default \ + --conf spark.kubernetes.executor.deleteOnTermination=false \ + --conf spark.kubernetes.driver.label.admission.datadoghq.com/enabled=true \ + --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark \ + --conf spark.kubernetes.authenticate.executor.serviceAccountName=spark \ + --conf spark.kubernetes.driver.annotation.admission.datadoghq.com/java-lib.custom-image=${LIB_INIT_IMAGE} \ + --conf spark.kubernetes.driverEnv.DD_APM_INSTRUMENTATION_DEBUG=true \ + --conf spark.kubernetes.driver.annotation.admission.datadoghq.com/apm-inject.version=${AUTO_INJECT_VERSION} \ + --conf spark.driver.extraJavaOptions="-Ddd.integrations.enabled=false -Ddd.data.jobs.enabled=true -Ddd.service=spark-pi-example -Ddd.env=test -Ddd.version=0.1.0 -Ddd.tags=team:djm" \ + --conf spark.kubernetes.driverEnv.HADOOP_HOME=/opt/hadoop/ \ + local:///opt/spark/examples/jars/spark-examples.jar 20 + +# start a long running server to keep the web-log up. +python3 -m http.server ${SERVER_PORT:-18080} \ No newline at end of file diff --git a/lib-injection/build/docker/java/dd-lib-java-init-test-app/build.gradle.kts b/lib-injection/build/docker/java/dd-lib-java-init-test-app/build.gradle.kts index 74d6c7393de..9fcde95e44b 100644 --- a/lib-injection/build/docker/java/dd-lib-java-init-test-app/build.gradle.kts +++ b/lib-injection/build/docker/java/dd-lib-java-init-test-app/build.gradle.kts @@ -1,4 +1,18 @@ import org.springframework.boot.gradle.tasks.bundling.BootBuildImage +import software.amazon.awssdk.services.ecr.EcrClient +import software.amazon.awssdk.services.ecr.model.AuthorizationData +import java.util.Base64 + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath(platform("software.amazon.awssdk:bom:2.20.121")) + classpath("software.amazon.awssdk:ecr") + classpath("software.amazon.awssdk:sts") // sts is required to use roleArn in aws profiles + } +} plugins { id("org.springframework.boot") version "2.7.2" @@ -31,23 +45,33 @@ tasks.withType { val dockerImageRepo: String? by project val resolvedDockerImageRepo: String = dockerImageRepo ?: "docker.io/" + System.getenv("DOCKER_USERNAME") + "/dd-lib-java-init-test-app" val dockerImageTag: String by project +val useDockerProxy: String? by project + tasks.named("bootBuildImage") { - val arch = System.getProperty("os.arch") imageName = "${resolvedDockerImageRepo}:${dockerImageTag}" - //if (arch == "aarch64"){ - // builder = "dashaun/builder:tiny" - // environment.set("BP_DATADOG_ENABLED","true") - //} - - //TODO Change to use images from gcr.io to aboud docker hub rate limits - //There is a bug: https://github.com/paketo-buildpacks/adoptium/issues/401 - //buildpacks = listOf( - // "gcr.io/paketo-buildpacks/adoptium:latest", - // "urn:cnb:builder:paketo-buildpacks/java" - //"urn:cnb:builder:paketo-buildpacks/java", - //"gcr.io/paketo-buildpacks/new-relic", - //"gcr.io/paketo-buildpacks/builder:base", - //"gcr.io/paketo-buildpacks/run:base-cnb", - //"gcr.io/paketo-buildpacks/adoptium:11.2.3" - //) + + if (useDockerProxy == null) { + builder = "paketobuildpacks/builder-jammy-java-tiny:0.0.11" + runImage = "paketobuildpacks/run-jammy-tiny:0.2.55" + } else { + // Use dockerhub mirror + builder = "669783387624.dkr.ecr.us-east-1.amazonaws.com/dockerhub/paketobuildpacks/builder-jammy-java-tiny:0.0.11" + runImage = "669783387624.dkr.ecr.us-east-1.amazonaws.com/dockerhub/paketobuildpacks/run-jammy-tiny:0.2.55" + + // Setup authentication + // https://stackoverflow.com/questions/65320552/publish-docker-images-using-spring-boot-plugin-without-credentials/76898025#76898025 + val ecrClient = EcrClient.builder().build() + val base64Token = ecrClient + .getAuthorizationToken() + .authorizationData()[0] + .authorizationToken() + val auth = String(Base64.getDecoder().decode(base64Token)).split(":") + + docker { + builderRegistry { + username = auth[0] + password = auth[1] + } + } + } } diff --git a/lib-injection/build/docker/java/enterprise/ee-app-ear/pom.xml b/lib-injection/build/docker/java/enterprise/ee-app-ear/pom.xml new file mode 100644 index 00000000000..9b9849c4baa --- /dev/null +++ b/lib-injection/build/docker/java/enterprise/ee-app-ear/pom.xml @@ -0,0 +1,67 @@ + + + 4.0.0 + + + ee-app + org.example + 1.0-SNAPSHOT + + + ee-app-ear + ear + + EAR application + + + + + + org.example + payment-service + war + + + org.example + order-service + war + + + + + ee-app + + + org.apache.maven.plugins + maven-ear-plugin + 3.3.0 + + 8 + + lib + + + + org.example + payment-service + + /payment-service + + + org.example + order-service + + /order-service + + + + + + + + + diff --git a/lib-injection/build/docker/java/enterprise/order-service/pom.xml b/lib-injection/build/docker/java/enterprise/order-service/pom.xml new file mode 100644 index 00000000000..a547bdc7350 --- /dev/null +++ b/lib-injection/build/docker/java/enterprise/order-service/pom.xml @@ -0,0 +1,65 @@ + + 4.0.0 + org.example + order-service + 1.0-SNAPSHOT + war + Order service + A starter Jakarta EE Project + + UTF-8 + yyyyMMdd'T'HHmmss + 2.0.0.Final + + + org.example + ee-app + 1.0-SNAPSHOT + + + + jakarta.platform + jakarta.jakartaee-api + 8.0.0 + provided + + + + ${project.artifactId} + + + maven-war-plugin + 3.4.0 + + + org.wildfly.plugins + wildfly-maven-plugin + ${version.wildfly.maven.plugin} + + + + + + + + default + + true + + + + + maven-surefire-plugin + 2.4.3 + + true + + + + + + + + diff --git a/lib-injection/build/docker/java/enterprise/order-service/src/main/java/com/andrea/MainServlet.java b/lib-injection/build/docker/java/enterprise/order-service/src/main/java/com/andrea/MainServlet.java new file mode 100644 index 00000000000..1ebe2ca47b2 --- /dev/null +++ b/lib-injection/build/docker/java/enterprise/order-service/src/main/java/com/andrea/MainServlet.java @@ -0,0 +1,16 @@ +package com.sample; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class MainServlet extends HttpServlet { + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + resp.setStatus(200); + resp.setContentType("text/html"); + resp.getOutputStream().println("

Welcome to the order service

"); + } +} diff --git a/lib-injection/build/docker/java/enterprise/order-service/src/main/webapp/WEB-INF/web.xml b/lib-injection/build/docker/java/enterprise/order-service/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..3c8f98ac820 --- /dev/null +++ b/lib-injection/build/docker/java/enterprise/order-service/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,15 @@ + + + + main + com.sample.MainServlet + + + main + /* + + + \ No newline at end of file diff --git a/lib-injection/build/docker/java/enterprise/order-service/src/main/webapp/index.html b/lib-injection/build/docker/java/enterprise/order-service/src/main/webapp/index.html new file mode 100644 index 00000000000..f91a5963e59 --- /dev/null +++ b/lib-injection/build/docker/java/enterprise/order-service/src/main/webapp/index.html @@ -0,0 +1,29 @@ + + + + Jakarta EE Demo + + + + +

Jakarta EE 8 Demo with WildFly

+
+

Insert a Property:

+
+ Key   Value   +
+
+ +
+ +
+

List all records:

+ Get Full List +
+ + + + + \ No newline at end of file diff --git a/lib-injection/build/docker/java/enterprise/order-service/untitled-web2.iml b/lib-injection/build/docker/java/enterprise/order-service/untitled-web2.iml new file mode 100644 index 00000000000..385656040bc --- /dev/null +++ b/lib-injection/build/docker/java/enterprise/order-service/untitled-web2.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib-injection/build/docker/java/enterprise/payment-service/pom.xml b/lib-injection/build/docker/java/enterprise/payment-service/pom.xml new file mode 100644 index 00000000000..6a3bda9f313 --- /dev/null +++ b/lib-injection/build/docker/java/enterprise/payment-service/pom.xml @@ -0,0 +1,65 @@ + + 4.0.0 + org.example + payment-service + 1.0-SNAPSHOT + war + Payment Service + A starter Jakarta EE Project + + UTF-8 + yyyyMMdd'T'HHmmss + 2.0.0.Final + + + org.example + ee-app + 1.0-SNAPSHOT + + + + jakarta.platform + jakarta.jakartaee-api + 8.0.0 + provided + + + + ${project.artifactId} + + + maven-war-plugin + 3.4.0 + + + org.wildfly.plugins + wildfly-maven-plugin + ${version.wildfly.maven.plugin} + + + + + + + + default + + true + + + + + maven-surefire-plugin + 2.4.3 + + true + + + + + + + + diff --git a/lib-injection/build/docker/java/enterprise/payment-service/src/main/java/com/sample/MainServlet.java b/lib-injection/build/docker/java/enterprise/payment-service/src/main/java/com/sample/MainServlet.java new file mode 100644 index 00000000000..bd9af6fdbed --- /dev/null +++ b/lib-injection/build/docker/java/enterprise/payment-service/src/main/java/com/sample/MainServlet.java @@ -0,0 +1,18 @@ +package com.sample; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import java.io.IOException; + +public class MainServlet extends HttpServlet { + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + resp.setStatus(200); + resp.setContentType("text/html"); + resp.getOutputStream().println("

Welcome to the payment service

"); + } +} diff --git a/lib-injection/build/docker/java/enterprise/payment-service/src/main/webapp/WEB-INF/web.xml b/lib-injection/build/docker/java/enterprise/payment-service/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..3c8f98ac820 --- /dev/null +++ b/lib-injection/build/docker/java/enterprise/payment-service/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,15 @@ + + + + main + com.sample.MainServlet + + + main + /* + + + \ No newline at end of file diff --git a/lib-injection/build/docker/java/enterprise/payment-service/src/main/webapp/index.html b/lib-injection/build/docker/java/enterprise/payment-service/src/main/webapp/index.html new file mode 100644 index 00000000000..f91a5963e59 --- /dev/null +++ b/lib-injection/build/docker/java/enterprise/payment-service/src/main/webapp/index.html @@ -0,0 +1,29 @@ + + + + Jakarta EE Demo + + + + +

Jakarta EE 8 Demo with WildFly

+
+

Insert a Property:

+
+ Key   Value   +
+
+ +
+ +
+

List all records:

+ Get Full List +
+ + + + + \ No newline at end of file diff --git a/lib-injection/build/docker/java/enterprise/pom.xml b/lib-injection/build/docker/java/enterprise/pom.xml new file mode 100644 index 00000000000..75b7d3fffff --- /dev/null +++ b/lib-injection/build/docker/java/enterprise/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + org.example + ee-app + 1.0-SNAPSHOT + pom + sample application + + + payment-service + order-service + ee-app-ear + + + + UTF-8 + + + + + + + org.example + payment-service + 1.0-SNAPSHOT + war + compile + + + org.example + order-service + 1.0-SNAPSHOT + war + compile + + + + + + + + + + maven-compiler-plugin + 2.3.2 + + 8 + 8 + + + + + + + diff --git a/lib-injection/build/docker/java/jdk7-app/Dockerfile b/lib-injection/build/docker/java/jdk7-app/Dockerfile index 29ddda47043..897f99f7180 100644 --- a/lib-injection/build/docker/java/jdk7-app/Dockerfile +++ b/lib-injection/build/docker/java/jdk7-app/Dockerfile @@ -2,4 +2,4 @@ FROM openjdk:7-alpine COPY . . RUN javac *.java -ENTRYPOINT ["java", "-cp", ".", "sunhttpd"] \ No newline at end of file +ENTRYPOINT ["java", "-cp", ".", "SimpleHttpServer"] \ No newline at end of file diff --git a/lib-injection/build/docker/java/jdk7-app/SimpleHttpServer.java b/lib-injection/build/docker/java/jdk7-app/SimpleHttpServer.java new file mode 100644 index 00000000000..e040c7907bb --- /dev/null +++ b/lib-injection/build/docker/java/jdk7-app/SimpleHttpServer.java @@ -0,0 +1,53 @@ +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.net.URI; +import java.util.concurrent.Executors; + +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +public class SimpleHttpServer { + public static void main(String[] args) throws IOException { + InetSocketAddress addr = new InetSocketAddress(18080); + HttpServer server = HttpServer.create(addr, 0); + server.createContext("/", new TestHandler()); + server.setExecutor(Executors.newCachedThreadPool()); + server.start(); + System.out.println("Server is listening on port 18080" ); + } +} + +/* Sample java handler +*/ +class TestHandler implements HttpHandler { + public void handle(HttpExchange exchange) throws IOException { + String requestMethod = exchange.getRequestMethod(); + if (requestMethod.equalsIgnoreCase("GET")) { + URI responseURI = exchange.getRequestURI(); + String pathName = responseURI.getPath(); + Headers responseHeaders = exchange.getResponseHeaders(); + responseHeaders.set("Content-Type", "text/plain"); + exchange.sendResponseHeaders(200, 0); + + OutputStream responseBody = exchange.getResponseBody(); + Headers requestHeaders = exchange.getRequestHeaders(); + Set keySet = requestHeaders.keySet(); + Iterator iter = keySet.iterator(); + while (iter.hasNext()) { + String key = iter.next(); + List values = requestHeaders.get(key); + String s = key + " = " + values.toString() + "\n"; + responseBody.write(s.getBytes()); + } + String pathString = "Pathname = " + pathName + "\n"; + responseBody.write(pathString.getBytes()); + responseBody.close(); + } + } +} \ No newline at end of file diff --git a/lib-injection/build/docker/java/jdk7-app/sunhttpd.java b/lib-injection/build/docker/java/jdk7-app/sunhttpd.java deleted file mode 100644 index a3ac6346e97..00000000000 --- a/lib-injection/build/docker/java/jdk7-app/sunhttpd.java +++ /dev/null @@ -1,53 +0,0 @@ -import java.io.IOException; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.net.URI; -import java.util.concurrent.Executors; - -import com.sun.net.httpserver.Headers; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; - -public class sunhttpd { - public static void main(String[] args) throws IOException { - InetSocketAddress addr = new InetSocketAddress(18080); - HttpServer server = HttpServer.create(addr, 0); - server.createContext("/", new TestHandler()); - server.setExecutor(Executors.newCachedThreadPool()); - server.start(); - System.out.println("Server is listening on port 18080" ); - } -} - -/* Sample java handler -*/ -class TestHandler implements HttpHandler { - public void handle(HttpExchange exchange) throws IOException { - String requestMethod = exchange.getRequestMethod(); - if (requestMethod.equalsIgnoreCase("GET")) { - URI responseURI = exchange.getRequestURI(); - String pathName = responseURI.getPath(); - Headers responseHeaders = exchange.getResponseHeaders(); - responseHeaders.set("Content-Type", "text/plain"); - exchange.sendResponseHeaders(200, 0); - - OutputStream responseBody = exchange.getResponseBody(); - Headers requestHeaders = exchange.getRequestHeaders(); - Set keySet = requestHeaders.keySet(); - Iterator iter = keySet.iterator(); - while (iter.hasNext()) { - String key = iter.next(); - List values = requestHeaders.get(key); - String s = key + " = " + values.toString() + "\n"; - responseBody.write(s.getBytes()); - } - String pathString = "Pathname = " + pathName + "\n"; - responseBody.write(pathString.getBytes()); - responseBody.close(); - } - } -} \ No newline at end of file diff --git a/lib-injection/build/docker/java/jetty-app/CrashServlet.java b/lib-injection/build/docker/java/jetty-app/CrashServlet.java new file mode 100644 index 00000000000..cf206269aac --- /dev/null +++ b/lib-injection/build/docker/java/jetty-app/CrashServlet.java @@ -0,0 +1,229 @@ +import java.io.*; +import java.lang.management.ManagementFactory; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.ServletException; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.webapp.WebAppContext; + + + +public class CrashServlet extends HttpServlet { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + // Check which endpoint is being accessed by looking at the request URI + String requestURI = req.getRequestURI(); + + if (requestURI.equals("/fork_and_crash")) { + handleForkAndCrash(req, resp); + } else if (requestURI.equals("/child_pids")) { + handleChildPids(req, resp); + } else if (requestURI.equals("/zombies")) { + handleZombies(req, resp); + } else { + // Return 404 if the endpoint is not recognized + resp.setStatus(HttpServletResponse.SC_NOT_FOUND); + resp.getWriter().println("Unknown endpoint"); + } + } + + private void handleForkAndCrash(HttpServletRequest req, HttpServletResponse resp) + throws IOException { + String result = forkAndCrash(); + + resp.setContentType("text/plain"); + resp.setStatus(HttpServletResponse.SC_OK); + resp.getWriter().println(result); + } + + private List getChildPidsFromProc(long parentPid) { + List childPids = new ArrayList<>(); + + // Iterate over all directories in /proc + File procDir = new File("/proc"); + File[] files = procDir.listFiles(); + + if (files != null) { + for (File file : files) { + // Skip non-numeric directories since only numeric names correspond to PIDs + if (file.isDirectory() && file.getName().matches("\\d+")) { + long pid = Long.parseLong(file.getName()); + long ppid = getParentPid(pid); + + // If the PPID matches the current process ID, add it to the list + // Filter out jps because it can be spawned by the java tracer + if (ppid == parentPid && !"jps".equals(getProcessName(pid))) { + childPids.add(pid); + } + } + } + } + + return childPids; + } + + private long getParentPid(long pid) { + File statusFile = new File("/proc/" + pid + "/status"); + + try (BufferedReader reader = new BufferedReader(new FileReader(statusFile))) { + String line; + while ((line = reader.readLine()) != null) { + if (line.startsWith("PPid:")) { + String[] parts = line.split("\\s+"); + return Long.parseLong(parts[1]); + } + } + } catch (IOException e) { + // In case of an error (e.g., process may have ended), return -1 + return -1; + } + + return -1; // Return -1 if we couldn't find the PPid field + } + + private String getProcessName(long pid) { + File commFile = new File("/proc/" + pid + "/comm"); + + try (BufferedReader reader = new BufferedReader(new FileReader(commFile))) { + return reader.readLine(); + } catch (IOException e) { + return null; + } + } + + private void handleChildPids(HttpServletRequest req, HttpServletResponse resp) + throws IOException { + try { + // Get current PID using ManagementFactory + String jvmName = ManagementFactory.getRuntimeMXBean().getName(); + long currentPid = Long.parseLong(jvmName.split("@")[0]); + + // Get the list of child PIDs by examining /proc + List childPids = getChildPidsFromProc(currentPid); + + // Prepare the response + StringBuilder response = new StringBuilder(); + for (Long pid : childPids) { + response.append("PID: ").append(pid).append("\n"); + } + + // Send response to the client + resp.setContentType("text/plain"); + resp.setStatus(HttpServletResponse.SC_OK); + resp.getWriter().println(response.toString()); + } catch (Exception e) { + resp.setContentType("text/plain"); + resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + resp.getWriter().println("Error: " + e.getMessage()); + } + } + + public void handleZombies(HttpServletRequest req, HttpServletResponse resp) throws IOException { + try { + List zombieProcesses = getZombieProcessesFromProc(); + + // Prepare the response + StringBuilder response = new StringBuilder(); + for (String process : zombieProcesses) { + response.append(process).append("\n"); + } + + // Send response to the client + resp.setContentType("text/plain"); + resp.setStatus(HttpServletResponse.SC_OK); + resp.getWriter().println(response.toString()); + } catch (Exception e) { + resp.setContentType("text/plain"); + resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + resp.getWriter().println("Error: " + e.getMessage()); + } + } + + private List getZombieProcessesFromProc() { + List zombieProcesses = new ArrayList<>(); + File procDir = new File("/proc"); + + // Iterate over all the directories in /proc + for (File file : procDir.listFiles()) { + if (file.isDirectory() && file.getName().matches("\\d+")) { + String pid = file.getName(); + File statusFile = new File(file, "status"); + + if (statusFile.exists()) { + try (BufferedReader reader = new BufferedReader(new FileReader(statusFile))) { + String name = null; + String state = null; + String ppid = null; + String line; + + while ((line = reader.readLine()) != null) { + if (line.startsWith("Name:")) { + String[] parts = line.split("\\s+"); + if (parts.length > 1) { + name = parts[1]; + } + } else if (line.startsWith("State:")) { + String[] parts = line.split("\\s+"); + if (parts.length > 1) { + state = parts[1]; + } + } else if (line.startsWith("PPid:")) { + String[] parts = line.split("\\s+"); + if (parts.length > 1) { + ppid = parts[1]; + } + } + + // Break early if all information is found + if (name != null && state != null && ppid != null) { + break; + } + } + + // Check if the process state is 'Z' (zombie) + if ("Z".equals(state)) { + zombieProcesses.add(String.format("%s (PID: %s, PPID: %s)", name, pid, ppid)); + } + } catch (IOException e) { + // Ignore errors reading individual process information + } + } + } + } + + return zombieProcesses; + } + + private static String forkAndCrash() + throws IOException { + try { + String commandLine = new String(Files.readAllBytes(Paths.get("/proc/self/cmdline"))); + + // Split by null characters, since arguments in /proc/self/cmdline are separated by \0 + String[] command = commandLine.split("\0"); + + // Add an additional argument to indicate that the child should crash + String[] modifiedCommand = Arrays.copyOf(command, command.length + 1); + modifiedCommand[command.length] = "--crash"; + + ProcessBuilder processBuilder = new ProcessBuilder(modifiedCommand); + processBuilder.inheritIO(); + + Process process = processBuilder.start(); + int exitCode = process.waitFor(); + return "Child process exited with code: " + exitCode; + } catch (InterruptedException e) { + return "Interrupted"; + } + } +} \ No newline at end of file diff --git a/lib-injection/build/docker/java/jetty-app/JettyServletMain.java b/lib-injection/build/docker/java/jetty-app/JettyServletMain.java new file mode 100644 index 00000000000..e2491f8d406 --- /dev/null +++ b/lib-injection/build/docker/java/jetty-app/JettyServletMain.java @@ -0,0 +1,57 @@ +import java.io.IOException; +import java.io.*; +import java.lang.management.ManagementFactory; +import java.lang.reflect.Field; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.ServletException; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.webapp.WebAppContext; +import sun.misc.Unsafe; + +/** + * Starts up a server that serves static files from the top-level directory. + */ +public class JettyServletMain { + + public static void main(String[] args) throws Exception { + + for (String arg : args) { + if (arg.equals("--crash")) { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + Unsafe unsafe = (Unsafe) f.get(null); + + // This will cause a segmentation fault by writing to address 0 + unsafe.putAddress(0, 0); + break; + } + } + + // Create a server that listens on port 8080. + Server server = new Server(18080); + WebAppContext webAppContext = new WebAppContext(); + server.setHandler(webAppContext); + + // Load static content from the top level directory. + URL webAppDir = JettyServletMain.class.getClassLoader().getResource("."); + webAppContext.setResourceBase(webAppDir.toURI().toString()); + + webAppContext.addServlet(new ServletHolder(new CrashServlet()), "/fork_and_crash"); + webAppContext.addServlet(new ServletHolder(new CrashServlet()), "/child_pids"); + webAppContext.addServlet(new ServletHolder(new CrashServlet()), "/zombies"); + + // Start the server! + server.start(); + System.out.println("Server started listening on port 18080!"); + + // Keep the main thread alive while the server is running. + server.join(); + } +} diff --git a/lib-injection/build/docker/nodejs/sample-app-node13/child.js b/lib-injection/build/docker/nodejs/sample-app-node13/child.js new file mode 100644 index 00000000000..e7f70e0c2c6 --- /dev/null +++ b/lib-injection/build/docker/nodejs/sample-app-node13/child.js @@ -0,0 +1,6 @@ +console.log('Child process started'); + +setTimeout(() => { + console.log('Child process exiting after 5 seconds'); + process.kill(process.pid, 'SIGSEGV'); +}, 5000); // Add a delay before crashing otherwise the telemetry forwarder leaves a zombie behind diff --git a/lib-injection/build/docker/nodejs/sample-app-node13/index.js b/lib-injection/build/docker/nodejs/sample-app-node13/index.js index e3fef4ae164..3d3408963cb 100644 --- a/lib-injection/build/docker/nodejs/sample-app-node13/index.js +++ b/lib-injection/build/docker/nodejs/sample-app-node13/index.js @@ -1,9 +1,119 @@ +const fs = require('fs'); +const path = require('path'); +const { fork } = require('child_process'); + process.on('SIGTERM', (signal) => { process.exit(0); }); +function forkAndCrash(req, res) { + const child = fork('child.js'); + + child.on('close', (code, signal) => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end(`Child process ${child.pid} exited with code ${code}, signal ${signal}`); + }); +} + +function getChildPids(req, res) { + const currentPid = process.pid; + + try { + // Get the list of all process directories in /proc + const procDir = '/proc'; + const procFiles = fs.readdirSync(procDir).filter(file => /^\d+$/.test(file)); + + let childPids = []; + + // Iterate through each process directory + procFiles.forEach(pid => { + const statusPath = path.join(procDir, pid, 'status'); + try { + if (fs.existsSync(statusPath)) { + const statusContent = fs.readFileSync(statusPath, 'utf8'); + + // Find the PPid line in the status file + const ppidMatch = statusContent.match(/^PPid:\s+(\d+)/m); + if (ppidMatch) { + const ppid = parseInt(ppidMatch[1], 10); + if (ppid === currentPid) { + childPids.push(pid); + } + } + } + } catch (error) { + if (error.code !== 'ESRCH') { + // Ignore ESRCH error, but throw other errors + throw error; + } + } + }); + + // Send response back + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end(`${childPids.join(', ')}`); + } catch (error) { + res.writeHead(500, { 'Content-Type': 'text/plain' }); + res.end(`Error: ${error.message}`); + } +} + +function getZombies(req, res) { + try { + const procDir = '/proc'; + const procFiles = fs.readdirSync(procDir).filter(file => /^\d+$/.test(file)); + let zombieProcesses = []; + + // Iterate through each process directory + procFiles.forEach(pid => { + const statusPath = path.join(procDir, pid, 'status'); + try { + if (fs.existsSync(statusPath)) { + const statusContent = fs.readFileSync(statusPath, 'utf8'); + + // Find the Name, State, and PPid lines in the status file + const nameMatch = statusContent.match(/^Name:\s+(\S+)/m); + const stateMatch = statusContent.match(/^State:\s+(\w)/m); + const ppidMatch = statusContent.match(/^PPid:\s+(\d+)/m); + + if (nameMatch && stateMatch && ppidMatch) { + const name = nameMatch[1]; + const state = stateMatch[1]; + const ppid = ppidMatch[1]; + + // Check if the process state is 'Z' (zombie) + if (state === 'Z') { + zombieProcesses.push(`${name} (PID: ${pid}, PPID: ${ppid})`); + } + } + } + } catch (error) { + if (error.code !== 'ESRCH') { + // Ignore ESRCH error, but throw other errors + throw error; + } + } + }); + + // Send response back + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end(`${zombieProcesses.join(', ')}`); + } catch (error) { + res.writeHead(500, { 'Content-Type': 'text/plain' }); + res.end(`Error: ${error.message}`); + } +} + require('http').createServer((req, res) => { - res.end('Hello, world!\n') + if (req.url === '/fork_and_crash') { + forkAndCrash(req, res); + } else if (req.url === '/child_pids') { + getChildPids(req, res); + } else if (req.url === '/zombies') { + getZombies(req, res); + } else { + res.end('Hello, world!\n') + } }).listen(18080, () => { console.log('listening on port 18080') // eslint-disable-line no-console }) diff --git a/lib-injection/build/docker/nodejs/sample-app/build.sh b/lib-injection/build/docker/nodejs/sample-app/build.sh index 985dd040619..9c2b6dc9f21 100755 --- a/lib-injection/build/docker/nodejs/sample-app/build.sh +++ b/lib-injection/build/docker/nodejs/sample-app/build.sh @@ -1,7 +1,7 @@ #!/bin/bash if [ -z "${BUILDX_PLATFORMS}" ] ; then - BUILDX_PLATFORMS=`docker buildx imagetools inspect --raw python:3.9 | jq -r 'reduce (.manifests[] | [ .platform.os, .platform.architecture, .platform.variant ] | join("/") | sub("\\/$"; "")) as $item (""; . + "," + $item)' | sed 's/,//'` + BUILDX_PLATFORMS=`docker buildx imagetools inspect --raw python:3.12 | jq -r 'reduce (.manifests[] | [ .platform.os, .platform.architecture, .platform.variant ] | join("/") | sub("\\/$"; "")) as $item (""; . + "," + $item)' | sed 's/,//'` fi echo "Build for platforms: ${BUILDX_PLATFORMS}" docker buildx build --platform ${BUILDX_PLATFORMS} --tag ${LIBRARY_INJECTION_TEST_APP_IMAGE} --push . \ No newline at end of file diff --git a/lib-injection/build/docker/nodejs/sample-app/child.js b/lib-injection/build/docker/nodejs/sample-app/child.js new file mode 100644 index 00000000000..2bcb586ff9d --- /dev/null +++ b/lib-injection/build/docker/nodejs/sample-app/child.js @@ -0,0 +1,6 @@ +console.log('Child process started'); + +setTimeout(function () { + console.log('Child process exiting after 5 seconds'); + process.kill(process.pid, 'SIGSEGV'); +}, 5000); // Add a delay before crashing otherwise the telemetry forwarder leaves a zombie behind diff --git a/lib-injection/build/docker/nodejs/sample-app/health.js b/lib-injection/build/docker/nodejs/sample-app/health.js new file mode 100644 index 00000000000..64a5f84885a --- /dev/null +++ b/lib-injection/build/docker/nodejs/sample-app/health.js @@ -0,0 +1,3 @@ +'use strict' + +require('http').get('http://127.0.0.1:18080') diff --git a/lib-injection/build/docker/nodejs/sample-app/index.js b/lib-injection/build/docker/nodejs/sample-app/index.js index e3fef4ae164..6e5b589088f 100644 --- a/lib-injection/build/docker/nodejs/sample-app/index.js +++ b/lib-injection/build/docker/nodejs/sample-app/index.js @@ -1,9 +1,134 @@ -process.on('SIGTERM', (signal) => { +var fs = require('fs'); +var path = require('path'); +var fork = require('child_process').fork; + +process.on('SIGTERM', function (signal) { process.exit(0); }); -require('http').createServer((req, res) => { - res.end('Hello, world!\n') -}).listen(18080, () => { +function crashme(req, res) { + setTimeout(function () { + process.kill(process.pid, 'SIGSEGV'); + + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('Crashing process ' + process.pid); + }, 2000); // Add a delay before crashing otherwise the telemetry forwarder leaves a zombie behind +} + +function forkAndCrash(req, res) { + var child = fork('child.js'); + + child.on('close', function (code, signal) { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('Child process ' + child.pid + ' exited with code ' + code + ', signal ' + signal); + }); +} + +function getChildPids(req, res) { + var currentPid = process.pid; + + try { + // Get the list of all process directories in /proc + var procDir = '/proc'; + var procFiles = fs.readdirSync(procDir).filter(function (file) { + return /^\d+$/.test(file) + }); + + var childPids = []; + + // Iterate through each process directory + procFiles.forEach(function (pid) { + var statusPath = path.join(procDir, pid, 'status'); + try { + if (fs.existsSync(statusPath)) { + var statusContent = fs.readFileSync(statusPath, 'utf8'); + + // Find the PPid line in the status file + var ppidMatch = statusContent.match(/^PPid:\s+(\d+)/m); + if (ppidMatch) { + var ppid = parseInt(ppidMatch[1], 10); + if (ppid === currentPid) { + childPids.push(pid); + } + } + } + } catch (error) { + if (error.code !== 'ESRCH') { + // Ignore ESRCH error, but throw other errors + throw error; + } + } + }); + + // Send response back + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end(childPids.join(', ')); + } catch (error) { + res.writeHead(500, { 'Content-Type': 'text/plain' }); + res.end('Error: ' + error.message); + } +} + +function getZombies(req, res) { + try { + var procDir = '/proc'; + var procFiles = fs.readdirSync(procDir).filter(function (file) { + return /^\d+$/.test(file) + }); + var zombieProcesses = []; + + // Iterate through each process directory + procFiles.forEach(function (pid) { + var statusPath = path.join(procDir, pid, 'status'); + try { + if (fs.existsSync(statusPath)) { + var statusContent = fs.readFileSync(statusPath, 'utf8'); + + // Find the Name, State, and PPid lines in the status file + var nameMatch = statusContent.match(/^Name:\s+(\S+)/m); + var stateMatch = statusContent.match(/^State:\s+(\w)/m); + var ppidMatch = statusContent.match(/^PPid:\s+(\d+)/m); + + if (nameMatch && stateMatch && ppidMatch) { + var name = nameMatch[1]; + var state = stateMatch[1]; + var ppid = ppidMatch[1]; + + // Check if the process state is 'Z' (zombie) + if (state === 'Z') { + zombieProcesses.push(name + ' (PID: ' + pid + ', PPID: ' + ppid + ')'); + } + } + } + } catch (error) { + if (error.code !== 'ESRCH') { + // Ignore ESRCH error, but throw other errors + throw error; + } + } + }); + + // Send response back + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end(zombieProcesses.join(', ')); + } catch (error) { + res.writeHead(500, { 'Content-Type': 'text/plain' }); + res.end('Error: ' + error.message); + } +} + +require('http').createServer(function (req, res) { + if (req.url === '/crashme') { + crashme(req, res); + } else if (req.url === '/fork_and_crash') { + forkAndCrash(req, res); + } else if (req.url === '/child_pids') { + getChildPids(req, res); + } else if (req.url === '/zombies') { + getZombies(req, res); + } else { + res.end('Hello, world!\n') + } +}).listen(18080, function () { console.log('listening on port 18080') // eslint-disable-line no-console }) diff --git a/lib-injection/build/docker/nodejs/sample-app/index.mjs b/lib-injection/build/docker/nodejs/sample-app/index.mjs new file mode 100644 index 00000000000..3084f3bd6c2 --- /dev/null +++ b/lib-injection/build/docker/nodejs/sample-app/index.mjs @@ -0,0 +1,11 @@ +process.on('SIGTERM', (signal) => { + process.exit(0); +}); + +import { createServer } from 'http'; + +createServer((req, res) => { + res.end('Hello, world!\n') +}).listen(18080, () => { + console.log('listening on port 18080') // eslint-disable-line no-console +}) diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-27/Dockerfile b/lib-injection/build/docker/python/dd-lib-python-init-test-django-27/Dockerfile new file mode 100644 index 00000000000..eea7cec4169 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-27/Dockerfile @@ -0,0 +1,12 @@ +FROM python:2.7 + +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django +EXPOSE 18080 + +# Many users run a non-root user, ensure this is supported by the injection mechanism +USER 1000 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-27/build.sh b/lib-injection/build/docker/python/dd-lib-python-init-test-django-27/build.sh new file mode 100755 index 00000000000..9340d6f6df6 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-27/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +if [ -z "${BUILDX_PLATFORMS}" ] ; then + BUILDX_PLATFORMS=`docker buildx imagetools inspect --raw python:3.12 | jq -r 'reduce (.manifests[] | [ .platform.os, .platform.architecture, .platform.variant ] | join("/") | sub("\\/$"; "")) as $item (""; . + "," + $item)' | sed 's/,//'` +fi +docker buildx build --platform ${BUILDX_PLATFORMS} --tag ${LIBRARY_INJECTION_TEST_APP_IMAGE} --push . \ No newline at end of file diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-27/django_app.py b/lib-injection/build/docker/python/dd-lib-python-init-test-django-27/django_app.py new file mode 100644 index 00000000000..94bc2275468 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-27/django_app.py @@ -0,0 +1,29 @@ +import os +import signal +import sys + +from django.http import HttpResponse +from django.conf.urls import url + + +def handle_sigterm(signo, sf): + sys.exit(0) + + +signal.signal(signal.SIGTERM, handle_sigterm) + + +filepath, extension = os.path.splitext(__file__) +ROOT_URLCONF = os.path.basename(filepath) +DEBUG = False +SECRET_KEY = "fdsfdasfa" +ALLOWED_HOSTS = ["*"] + + +def index(request): + return HttpResponse("test") + + +urlpatterns = [ + url("", index), +] diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn-alpine/Dockerfile b/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn-alpine/Dockerfile new file mode 100644 index 00000000000..9ae517c6c71 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn-alpine/Dockerfile @@ -0,0 +1,9 @@ +FROM python:3.10-alpine + +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django gunicorn +EXPOSE 18080 +CMD gunicorn --bind :18080 django_app:application diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn-alpine/build.sh b/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn-alpine/build.sh new file mode 100755 index 00000000000..9340d6f6df6 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn-alpine/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +if [ -z "${BUILDX_PLATFORMS}" ] ; then + BUILDX_PLATFORMS=`docker buildx imagetools inspect --raw python:3.12 | jq -r 'reduce (.manifests[] | [ .platform.os, .platform.architecture, .platform.variant ] | join("/") | sub("\\/$"; "")) as $item (""; . + "," + $item)' | sed 's/,//'` +fi +docker buildx build --platform ${BUILDX_PLATFORMS} --tag ${LIBRARY_INJECTION_TEST_APP_IMAGE} --push . \ No newline at end of file diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn-alpine/django_app.py b/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn-alpine/django_app.py new file mode 100644 index 00000000000..0d16bb91249 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn-alpine/django_app.py @@ -0,0 +1,31 @@ +import os +import signal +import sys + +from django.core.wsgi import get_wsgi_application +from django.http import HttpResponse +from django.urls import path + + +def handle_sigterm(signo, sf): + sys.exit(0) + + +signal.signal(signal.SIGTERM, handle_sigterm) + +filepath, extension = os.path.splitext(__file__) +ROOT_URLCONF = os.path.basename(filepath) +DEBUG = False +SECRET_KEY = "fdsfdasfa" +ALLOWED_HOSTS = ["*"] + + +def index(request): + return HttpResponse("test") + + +urlpatterns = [ + path("", index), +] + +application = get_wsgi_application() diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn/Dockerfile b/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn/Dockerfile index 4a944cec744..cfb3c5225c4 100644 --- a/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn/Dockerfile +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9 +FROM python:3.10 ENV PYTHONUNBUFFERED 1 ENV DJANGO_SETTINGS_MODULE django_app diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn/build.sh b/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn/build.sh index a44f6aefff1..9340d6f6df6 100755 --- a/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn/build.sh +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-gunicorn/build.sh @@ -1,6 +1,6 @@ #!/bin/bash if [ -z "${BUILDX_PLATFORMS}" ] ; then - BUILDX_PLATFORMS=`docker buildx imagetools inspect --raw python:3.9 | jq -r 'reduce (.manifests[] | [ .platform.os, .platform.architecture, .platform.variant ] | join("/") | sub("\\/$"; "")) as $item (""; . + "," + $item)' | sed 's/,//'` + BUILDX_PLATFORMS=`docker buildx imagetools inspect --raw python:3.12 | jq -r 'reduce (.manifests[] | [ .platform.os, .platform.architecture, .platform.variant ] | join("/") | sub("\\/$"; "")) as $item (""; . + "," + $item)' | sed 's/,//'` fi docker buildx build --platform ${BUILDX_PLATFORMS} --tag ${LIBRARY_INJECTION_TEST_APP_IMAGE} --push . \ No newline at end of file diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-preinstalled/Dockerfile b/lib-injection/build/docker/python/dd-lib-python-init-test-django-preinstalled/Dockerfile new file mode 100644 index 00000000000..5b4ad5c2e1e --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-preinstalled/Dockerfile @@ -0,0 +1,14 @@ +FROM python:3.9 + +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src + +# Install ddtrace beforehand to ensure it doesn't get overridden. +RUN pip install django ddtrace==1.12.0 +EXPOSE 18080 + +# Many users run a non-root user, ensure this is supported by the injection mechanism +USER 1000 +CMD ddtrace-run python -m django runserver 0.0.0.0:18080 diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-preinstalled/build.sh b/lib-injection/build/docker/python/dd-lib-python-init-test-django-preinstalled/build.sh new file mode 100755 index 00000000000..9340d6f6df6 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-preinstalled/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +if [ -z "${BUILDX_PLATFORMS}" ] ; then + BUILDX_PLATFORMS=`docker buildx imagetools inspect --raw python:3.12 | jq -r 'reduce (.manifests[] | [ .platform.os, .platform.architecture, .platform.variant ] | join("/") | sub("\\/$"; "")) as $item (""; . + "," + $item)' | sed 's/,//'` +fi +docker buildx build --platform ${BUILDX_PLATFORMS} --tag ${LIBRARY_INJECTION_TEST_APP_IMAGE} --push . \ No newline at end of file diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-preinstalled/django_app.py b/lib-injection/build/docker/python/dd-lib-python-init-test-django-preinstalled/django_app.py new file mode 100644 index 00000000000..10d2b06b60b --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-preinstalled/django_app.py @@ -0,0 +1,38 @@ +import os +import signal +import sys + +from django.http import HttpResponse +from django.urls import path + + +def handle_sigterm(signo, sf): + sys.exit(0) + + +signal.signal(signal.SIGTERM, handle_sigterm) + + +filepath, extension = os.path.splitext(__file__) +ROOT_URLCONF = os.path.basename(filepath) +DEBUG = False +SECRET_KEY = "fdsfdasfa" +ALLOWED_HOSTS = ["*"] + + +def index(request): + import ddtrace + + if ddtrace.__version__ != "1.12.0": + print( + "Assertion failure: unexpected ddtrace version received. Got %r when expecting '1.12.0'" + % ddtrace.__version__ + ) + # Hard exit so traces aren't flushed. + os._exit(1) + return HttpResponse("test") + + +urlpatterns = [ + path("", index), +] diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-unsupported-package-force/Dockerfile b/lib-injection/build/docker/python/dd-lib-python-init-test-django-unsupported-package-force/Dockerfile new file mode 100644 index 00000000000..54769a5ec56 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-unsupported-package-force/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3.11 + +ENV PYTHONUNBUFFERED 1 +ENV DD_INJECT_FORCE 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django structlog==16.0.0 + +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-unsupported-package-force/build.sh b/lib-injection/build/docker/python/dd-lib-python-init-test-django-unsupported-package-force/build.sh new file mode 100755 index 00000000000..9340d6f6df6 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-unsupported-package-force/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +if [ -z "${BUILDX_PLATFORMS}" ] ; then + BUILDX_PLATFORMS=`docker buildx imagetools inspect --raw python:3.12 | jq -r 'reduce (.manifests[] | [ .platform.os, .platform.architecture, .platform.variant ] | join("/") | sub("\\/$"; "")) as $item (""; . + "," + $item)' | sed 's/,//'` +fi +docker buildx build --platform ${BUILDX_PLATFORMS} --tag ${LIBRARY_INJECTION_TEST_APP_IMAGE} --push . \ No newline at end of file diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-unsupported-package-force/django_app.py b/lib-injection/build/docker/python/dd-lib-python-init-test-django-unsupported-package-force/django_app.py new file mode 100644 index 00000000000..77116f1a3f7 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-unsupported-package-force/django_app.py @@ -0,0 +1,29 @@ +import os +import signal +import sys + +from django.http import HttpResponse +from django.urls import path + + +def handle_sigterm(signo, sf): + sys.exit(0) + + +signal.signal(signal.SIGTERM, handle_sigterm) + + +filepath, extension = os.path.splitext(__file__) +ROOT_URLCONF = os.path.basename(filepath) +DEBUG = False +SECRET_KEY = "fdsfdasfa" +ALLOWED_HOSTS = ["*"] + + +def index(request): + return HttpResponse("test") + + +urlpatterns = [ + path("", index), +] diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-uvicorn/Dockerfile b/lib-injection/build/docker/python/dd-lib-python-init-test-django-uvicorn/Dockerfile index 90465d5ef19..93ece8243df 100644 --- a/lib-injection/build/docker/python/dd-lib-python-init-test-django-uvicorn/Dockerfile +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-uvicorn/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9 +FROM python:3.12 ENV PYTHONUNBUFFERED 1 ENV DJANGO_SETTINGS_MODULE django_app diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django-uvicorn/build.sh b/lib-injection/build/docker/python/dd-lib-python-init-test-django-uvicorn/build.sh index a44f6aefff1..9340d6f6df6 100755 --- a/lib-injection/build/docker/python/dd-lib-python-init-test-django-uvicorn/build.sh +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django-uvicorn/build.sh @@ -1,6 +1,6 @@ #!/bin/bash if [ -z "${BUILDX_PLATFORMS}" ] ; then - BUILDX_PLATFORMS=`docker buildx imagetools inspect --raw python:3.9 | jq -r 'reduce (.manifests[] | [ .platform.os, .platform.architecture, .platform.variant ] | join("/") | sub("\\/$"; "")) as $item (""; . + "," + $item)' | sed 's/,//'` + BUILDX_PLATFORMS=`docker buildx imagetools inspect --raw python:3.12 | jq -r 'reduce (.manifests[] | [ .platform.os, .platform.architecture, .platform.variant ] | join("/") | sub("\\/$"; "")) as $item (""; . + "," + $item)' | sed 's/,//'` fi docker buildx build --platform ${BUILDX_PLATFORMS} --tag ${LIBRARY_INJECTION_TEST_APP_IMAGE} --push . \ No newline at end of file diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django/Dockerfile b/lib-injection/build/docker/python/dd-lib-python-init-test-django/Dockerfile index e7158f26477..d64fbe81410 100644 --- a/lib-injection/build/docker/python/dd-lib-python-init-test-django/Dockerfile +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9 +FROM python:3.11 ENV PYTHONUNBUFFERED 1 ENV DJANGO_SETTINGS_MODULE django_app @@ -6,4 +6,7 @@ WORKDIR /src ADD . /src RUN pip install django EXPOSE 18080 -CMD python -m django runserver 0.0.0.0:18080 + +# Many users run a non-root user, ensure this is supported by the injection mechanism +USER 1000 +CMD python -m django runserver 0.0.0.0:18080 \ No newline at end of file diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django/build.sh b/lib-injection/build/docker/python/dd-lib-python-init-test-django/build.sh index a44f6aefff1..9340d6f6df6 100755 --- a/lib-injection/build/docker/python/dd-lib-python-init-test-django/build.sh +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django/build.sh @@ -1,6 +1,6 @@ #!/bin/bash if [ -z "${BUILDX_PLATFORMS}" ] ; then - BUILDX_PLATFORMS=`docker buildx imagetools inspect --raw python:3.9 | jq -r 'reduce (.manifests[] | [ .platform.os, .platform.architecture, .platform.variant ] | join("/") | sub("\\/$"; "")) as $item (""; . + "," + $item)' | sed 's/,//'` + BUILDX_PLATFORMS=`docker buildx imagetools inspect --raw python:3.12 | jq -r 'reduce (.manifests[] | [ .platform.os, .platform.architecture, .platform.variant ] | join("/") | sub("\\/$"; "")) as $item (""; . + "," + $item)' | sed 's/,//'` fi docker buildx build --platform ${BUILDX_PLATFORMS} --tag ${LIBRARY_INJECTION_TEST_APP_IMAGE} --push . \ No newline at end of file diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-django/django_app.py b/lib-injection/build/docker/python/dd-lib-python-init-test-django/django_app.py index 77116f1a3f7..6888ba54e1e 100644 --- a/lib-injection/build/docker/python/dd-lib-python-init-test-django/django_app.py +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-django/django_app.py @@ -1,6 +1,8 @@ import os import signal +import subprocess import sys +import time from django.http import HttpResponse from django.urls import path @@ -24,6 +26,93 @@ def index(request): return HttpResponse("test") +def crashme(request): + import ctypes + + ctypes.string_at(0) + + +def fork_and_crash(request): + pid = os.fork() + if pid > 0: + # Parent process + _, status = os.waitpid(pid, 0) # Wait for the child process to exit + return HttpResponse(f"Child process {pid} exited with status {status}") + elif pid == 0: + # Child process + time.sleep(5) # don't crash immediately or the telemetry forwarder leaves a zombie behind + crashme(request) + return HttpResponse("Nobody should see this") + + +def child_pids(request): + current_pid = os.getpid() + child_pids = [] + + # Iterate over all directories in /proc to look for PIDs + try: + for pid in os.listdir("/proc"): + if pid.isdigit(): + status_path = f"/proc/{pid}/status" + try: + with open(status_path, "r") as status_file: + for line in status_file: + if line.startswith("PPid:"): + ppid = int(line.split()[1]) + if ppid == current_pid: + child_pids.append(pid) + break + except (FileNotFoundError, PermissionError): + # Process might have terminated or we don't have permission + continue + + # Format the response to include the list of child PIDs + response_content = ", ".join(child_pids) + return HttpResponse(response_content, content_type="text/plain") + except Exception as e: + return HttpResponse(f"Error: {str(e)}", status=500, content_type="text/plain") + + +def zombies(request): + zombie_processes = [] + + # Iterate over all directories in /proc to look for PIDs + try: + for pid in os.listdir("/proc"): + if pid.isdigit(): + status_path = f"/proc/{pid}/status" + try: + with open(status_path, "r") as status_file: + state = None + name = None + ppid = None + for line in status_file: + if line.startswith("State:"): + state = line.split()[1] + elif line.startswith("Name:"): + name = line.split()[1] + elif line.startswith("PPid:"): + ppid = line.split()[1] + if state and name and ppid: + break + # Check if the process state is 'Z' (zombie) + if state == "Z": + zombie_processes.append(f"{name} (PID: {pid}, PPID: {ppid})") + except (FileNotFoundError, PermissionError): + # Process might have terminated or we don't have permission + continue + + # Format the response to include the list of zombie processes with their names, PIDs, and PPIDs + response_content = ", ".join(zombie_processes) + return HttpResponse(response_content, content_type="text/plain") + except Exception as e: + return HttpResponse(f"Error: {str(e)}", status=500, content_type="text/plain") + + urlpatterns = [ path("", index), + path("crashme", crashme), + path("fork_and_crash", fork_and_crash), + path("child_pids", child_pids), + path("zombies", zombies), ] diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/Dockerfile b/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/Dockerfile new file mode 100644 index 00000000000..15b4c92bbf1 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.8 + +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src + +RUN pip install django protobuf==3.17.0 + +# Many users run a non-root user, ensure this is supported by the injection mechanism +USER 1000 +CMD ["python","-m","django","runserver","0.0.0.0:18080"] diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/Readme.md b/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/Readme.md new file mode 100644 index 00000000000..dd922aef651 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/Readme.md @@ -0,0 +1,21 @@ +# Purpose + +This is a regression test to detect situations where: +1. autoinject erroneously brings in a new version of protobuf, causing issues processing pb.py files generated with an old version of protoc +2. when the profiler is loaded, it tries to load its own pb.py files with the customer's old version of protobuf, which cannot process its too-new pb.py files + + +# How to reproduce the test itself + +This test uses assets which were generated outside of the test itself. +At the time of writing, the following works to generate the required assets + +``` +wget -c https://github.com/protocolbuffers/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.bz2 +tar -xvf protobuf-2.6.1.tar.bz2 +pushd protobuf-2.6.1 +./configure && make -j +popd +mv ./protobuf-2.6.1/examples/addressbook.proto . +./protobuf-2.6.1/src/protoc --python_out=. addressbook.proto +``` diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/addressbook_pb2.py b/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/addressbook_pb2.py new file mode 100644 index 00000000000..5d755eb23e9 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/addressbook_pb2.py @@ -0,0 +1,270 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: addressbook.proto + +import sys + + +_b = sys.version_info[0] < 3 and (lambda x: x) or (lambda x: x.encode("latin1")) +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pb2 +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database + + +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor.FileDescriptor( + name="addressbook.proto", + package="tutorial", + serialized_pb=_b( + '\n\x11\x61\x64\x64ressbook.proto\x12\x08tutorial"\xda\x01\n\x06Person\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\n\n\x02id\x18\x02 \x02(\x05\x12\r\n\x05\x65mail\x18\x03 \x01(\t\x12+\n\x05phone\x18\x04 \x03(\x0b\x32\x1c.tutorial.Person.PhoneNumber\x1aM\n\x0bPhoneNumber\x12\x0e\n\x06number\x18\x01 \x02(\t\x12.\n\x04type\x18\x02 \x01(\x0e\x32\x1a.tutorial.Person.PhoneType:\x04HOME"+\n\tPhoneType\x12\n\n\x06MOBILE\x10\x00\x12\x08\n\x04HOME\x10\x01\x12\x08\n\x04WORK\x10\x02"/\n\x0b\x41\x64\x64ressBook\x12 \n\x06person\x18\x01 \x03(\x0b\x32\x10.tutorial.PersonB)\n\x14\x63om.example.tutorialB\x11\x41\x64\x64ressBookProtos' + ), +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + + +_PERSON_PHONETYPE = _descriptor.EnumDescriptor( + name="PhoneType", + full_name="tutorial.Person.PhoneType", + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor(name="MOBILE", index=0, number=0, options=None, type=None), + _descriptor.EnumValueDescriptor(name="HOME", index=1, number=1, options=None, type=None), + _descriptor.EnumValueDescriptor(name="WORK", index=2, number=2, options=None, type=None), + ], + containing_type=None, + options=None, + serialized_start=207, + serialized_end=250, +) +_sym_db.RegisterEnumDescriptor(_PERSON_PHONETYPE) + + +_PERSON_PHONENUMBER = _descriptor.Descriptor( + name="PhoneNumber", + full_name="tutorial.Person.PhoneNumber", + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name="number", + full_name="tutorial.Person.PhoneNumber.number", + index=0, + number=1, + type=9, + cpp_type=9, + label=2, + has_default_value=False, + default_value=_b("").decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + ), + _descriptor.FieldDescriptor( + name="type", + full_name="tutorial.Person.PhoneNumber.type", + index=1, + number=2, + type=14, + cpp_type=8, + label=1, + has_default_value=True, + default_value=1, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + ), + ], + extensions=[], + nested_types=[], + enum_types=[], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[], + serialized_start=128, + serialized_end=205, +) + +_PERSON = _descriptor.Descriptor( + name="Person", + full_name="tutorial.Person", + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name="name", + full_name="tutorial.Person.name", + index=0, + number=1, + type=9, + cpp_type=9, + label=2, + has_default_value=False, + default_value=_b("").decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + ), + _descriptor.FieldDescriptor( + name="id", + full_name="tutorial.Person.id", + index=1, + number=2, + type=5, + cpp_type=1, + label=2, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + ), + _descriptor.FieldDescriptor( + name="email", + full_name="tutorial.Person.email", + index=2, + number=3, + type=9, + cpp_type=9, + label=1, + has_default_value=False, + default_value=_b("").decode("utf-8"), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + ), + _descriptor.FieldDescriptor( + name="phone", + full_name="tutorial.Person.phone", + index=3, + number=4, + type=11, + cpp_type=10, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + ), + ], + extensions=[], + nested_types=[_PERSON_PHONENUMBER,], + enum_types=[_PERSON_PHONETYPE,], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[], + serialized_start=32, + serialized_end=250, +) + + +_ADDRESSBOOK = _descriptor.Descriptor( + name="AddressBook", + full_name="tutorial.AddressBook", + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name="person", + full_name="tutorial.AddressBook.person", + index=0, + number=1, + type=11, + cpp_type=10, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + ), + ], + extensions=[], + nested_types=[], + enum_types=[], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[], + serialized_start=252, + serialized_end=299, +) + +_PERSON_PHONENUMBER.fields_by_name["type"].enum_type = _PERSON_PHONETYPE +_PERSON_PHONENUMBER.containing_type = _PERSON +_PERSON.fields_by_name["phone"].message_type = _PERSON_PHONENUMBER +_PERSON_PHONETYPE.containing_type = _PERSON +_ADDRESSBOOK.fields_by_name["person"].message_type = _PERSON +DESCRIPTOR.message_types_by_name["Person"] = _PERSON +DESCRIPTOR.message_types_by_name["AddressBook"] = _ADDRESSBOOK + +Person = _reflection.GeneratedProtocolMessageType( + "Person", + (_message.Message,), + dict( + PhoneNumber=_reflection.GeneratedProtocolMessageType( + "PhoneNumber", + (_message.Message,), + dict( + DESCRIPTOR=_PERSON_PHONENUMBER, + __module__="addressbook_pb2" + # @@protoc_insertion_point(class_scope:tutorial.Person.PhoneNumber) + ), + ), + DESCRIPTOR=_PERSON, + __module__="addressbook_pb2" + # @@protoc_insertion_point(class_scope:tutorial.Person) + ), +) +_sym_db.RegisterMessage(Person) +_sym_db.RegisterMessage(Person.PhoneNumber) + +AddressBook = _reflection.GeneratedProtocolMessageType( + "AddressBook", + (_message.Message,), + dict( + DESCRIPTOR=_ADDRESSBOOK, + __module__="addressbook_pb2" + # @@protoc_insertion_point(class_scope:tutorial.AddressBook) + ), +) +_sym_db.RegisterMessage(AddressBook) + + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions( + descriptor_pb2.FileOptions(), _b("\n\024com.example.tutorialB\021AddressBookProtos") +) +# @@protoc_insertion_point(module_scope) diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/build.sh b/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/build.sh new file mode 100755 index 00000000000..9340d6f6df6 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +if [ -z "${BUILDX_PLATFORMS}" ] ; then + BUILDX_PLATFORMS=`docker buildx imagetools inspect --raw python:3.12 | jq -r 'reduce (.manifests[] | [ .platform.os, .platform.architecture, .platform.variant ] | join("/") | sub("\\/$"; "")) as $item (""; . + "," + $item)' | sed 's/,//'` +fi +docker buildx build --platform ${BUILDX_PLATFORMS} --tag ${LIBRARY_INJECTION_TEST_APP_IMAGE} --push . \ No newline at end of file diff --git a/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/django_app.py b/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/django_app.py new file mode 100644 index 00000000000..f0660889178 --- /dev/null +++ b/lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/django_app.py @@ -0,0 +1,39 @@ +import os +import signal +import sys + +from django.http import HttpResponse +from django.urls import path + +import addressbook_pb2 + + +def handle_sigterm(signo, sf): + sys.exit(0) + + +signal.signal(signal.SIGTERM, handle_sigterm) + + +filepath, extension = os.path.splitext(__file__) +ROOT_URLCONF = os.path.basename(filepath) +DEBUG = False +SECRET_KEY = "fdsfdasfa" +ALLOWED_HOSTS = ["*"] + + +def index(request): + # Do some stuff with the protobuf + person = addressbook_pb2.Person() + person.id = 1234 + person.name = "John Doe" + person.email = "john@ibm.com" + + print(person) + + return HttpResponse("test") + + +urlpatterns = [ + path("", index), +] diff --git a/lib-injection/build/docker/ruby/lib_injection_rails_app/Gemfile b/lib-injection/build/docker/ruby/lib_injection_rails_app/Gemfile index 494f8fee14e..1d23f77fdf3 100644 --- a/lib-injection/build/docker/ruby/lib_injection_rails_app/Gemfile +++ b/lib-injection/build/docker/ruby/lib_injection_rails_app/Gemfile @@ -13,6 +13,10 @@ gem "sqlite3", "~> 1.4" # Use the Puma web server [https://github.com/puma/puma] gem "puma", "~> 5.0" +gem 'mutex_m', '~> 0.2.0' +gem 'base64', '~> 0.1.0' +gem 'bigdecimal', '~> 1.2', '>= 1.2.7' + # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ] diff --git a/lib-injection/build/docker/ruby/lib_injection_rails_app/app/controllers/datadog_controller.rb b/lib-injection/build/docker/ruby/lib_injection_rails_app/app/controllers/datadog_controller.rb new file mode 100644 index 00000000000..657a31ffdf5 --- /dev/null +++ b/lib-injection/build/docker/ruby/lib_injection_rails_app/app/controllers/datadog_controller.rb @@ -0,0 +1,92 @@ +class DatadogController < ApplicationController + def fork_and_crash + pid = Process.fork do + Process.kill('SEGV', Process.pid) + end + + Process.wait(pid) + end + + def child_pids + current_pid = Process.pid + child_pids = [] + + begin + # Iterate over all the directories in /proc + Dir.foreach('/proc') do |pid| + # Skip non-numeric directories + next unless pid =~ /^\d+$/ + + status_path = "/proc/#{pid}/status" + + # Read the status file for each process + if File.exist?(status_path) + File.open(status_path) do |file| + file.each_line do |line| + if line.start_with?("PPid:") + ppid = line.split[1].to_i + if ppid == current_pid + child_pids << pid + end + break + end + end + end + end + end + + # Render the response with the list of child PIDs + render plain: "#{child_pids.join(', ')}" + rescue => e + # Handle any errors that might occur during reading from /proc + render plain: "Error: #{e.message}", status: 500 + end + end + + def zombies + zombie_processes = [] + + begin + # Iterate over all the directories in /proc + Dir.foreach('/proc') do |pid| + # Skip non-numeric directories + next unless pid =~ /^\d+$/ + + status_path = "/proc/#{pid}/status" + + # Read the status file for each process + if File.exist?(status_path) + name = nil + state = nil + ppid = nil + + File.open(status_path) do |file| + file.each_line do |line| + if line.start_with?("Name:") + name = line.split[1] + elsif line.start_with?("State:") + state = line.split[1] + elsif line.start_with?("PPid:") + ppid = line.split[1] + end + + # Break early if all information is found + break if name && state && ppid + end + end + + # Check if the process state is 'Z' (zombie) + if state == "Z" + zombie_processes << "#{name} (PID: #{pid}, PPID: #{ppid})" + end + end + end + + # Render the response with the list of zombie processes + render plain: zombie_processes.join(', ') + rescue => e + # Handle any errors that might occur during reading from /proc + render plain: "Error: #{e.message}", status: 500 + end + end + end \ No newline at end of file diff --git a/lib-injection/build/docker/ruby/lib_injection_rails_app/config/routes.rb b/lib-injection/build/docker/ruby/lib_injection_rails_app/config/routes.rb index 262ffd54723..889b1634607 100644 --- a/lib-injection/build/docker/ruby/lib_injection_rails_app/config/routes.rb +++ b/lib-injection/build/docker/ruby/lib_injection_rails_app/config/routes.rb @@ -3,4 +3,7 @@ # Defines the root path route ("/") # root "articles#index" + get 'fork_and_crash', controller: 'datadog', action: :fork_and_crash + get 'child_pids', controller: 'datadog', action: :child_pids + get 'zombies', controller: 'datadog', action: :zombies end diff --git a/manifests/cpp.yml b/manifests/cpp.yml index b90310c7529..7eb456e0ce9 100644 --- a/manifests/cpp.yml +++ b/manifests/cpp.yml @@ -11,6 +11,7 @@ tests/: test_schemas.py: irrelevant (ASM is not implemented in C++) iast/: sink/: + test_code_injection.py: irrelevant (ASM is not implemented in C++) test_command_injection.py: irrelevant (ASM is not implemented in C++) test_hardcoded_passwords.py: irrelevant (ASM is not implemented in C++) test_hardcoded_secrets.py: irrelevant (ASM is not implemented in C++) @@ -26,7 +27,9 @@ tests/: test_reflection_injection.py: irrelevant (ASM is not implemented in C++) test_sql_injection.py: irrelevant (ASM is not implemented in C++) test_ssrf.py: irrelevant (ASM is not implemented in C++) + test_template_injection.py: irrelevant (ASM is not implemented in C++) test_trust_boundary_violation.py: irrelevant (ASM is not implemented in C++) + test_untrusted_deserialization.py: irrelevant (ASM is not implemented in C++) test_unvalidated_redirect.py: irrelevant (ASM is not implemented in C++) test_unvalidated_redirect_forward.py: irrelevant (ASM is not implemented in C++) test_weak_cipher.py: irrelevant (ASM is not implemented in C++) @@ -48,13 +51,15 @@ tests/: test_parameter_name.py: irrelevant (ASM is not implemented in C++) test_parameter_value.py: irrelevant (ASM is not implemented in C++) test_path.py: irrelevant (ASM is not implemented in C++) + test_path_parameter.py: irrelevant (ASM is not implemented in C++) + test_sql_row.py: irrelevant (ASM is not implemented in C++) test_uri.py: irrelevant (ASM is not implemented in C++) rasp/: + test_cmdi.py: irrelevant (ASM is not implemented in C++) test_lfi.py: irrelevant (ASM is not implemented in C++) - test_span_tags.py: irrelevant (ASM is not implemented in C++) + test_shi.py: irrelevant (ASM is not implemented in C++) test_sqli.py: irrelevant (ASM is not implemented in C++) test_ssrf.py: irrelevant (ASM is not implemented in C++) - test_stack_traces.py: irrelevant (ASM is not implemented in C++) waf/: test_addresses.py: irrelevant (ASM is not implemented in C++) test_blocking.py: irrelevant (ASM is not implemented in C++) @@ -64,36 +69,41 @@ tests/: test_reports.py: irrelevant (ASM is not implemented in C++) test_rules.py: irrelevant (ASM is not implemented in C++) test_telemetry.py: irrelevant (ASM is not implemented in C++) - test_PII.py: irrelevant (ASM is not implemented in C++) test_alpha.py: irrelevant (ASM is not implemented in C++) test_asm_standalone.py: irrelevant (ASM is not implemented in C++) test_automated_login_events.py: irrelevant (ASM is not implemented in C++) + test_automated_user_and_session_tracking.py: irrelevant (ASM is not implemented in C++) test_blocking_addresses.py: irrelevant (ASM is not implemented in C++) test_client_ip.py: irrelevant (ASM is not implemented in C++) test_conf.py: irrelevant (ASM is not implemented in C++) test_customconf.py: irrelevant (ASM is not implemented in C++) test_event_tracking.py: irrelevant (ASM is not implemented in C++) + test_fingerprinting.py: irrelevant (ASM is not implemented in C++) test_identify.py: irrelevant (ASM is not implemented in C++) test_ip_blocking_full_denylist.py: irrelevant (ASM is not implemented in C++) test_logs.py: irrelevant (ASM is not implemented in C++) + test_metastruct.py: irrelevant (ASM is not implemented in C++) test_rate_limiter.py: irrelevant (ASM is not implemented in C++) + test_remote_config_rule_changes.py: irrelevant (ASM is not implemented in C++) test_reports.py: irrelevant (ASM is not implemented in C++) test_request_blocking.py: irrelevant (ASM is not implemented in C++) test_runtime_activation.py: irrelevant (ASM is not implemented in C++) test_shell_execution.py: irrelevant (ASM is not implemented in C++) + test_suspicious_attacker_blocking.py: irrelevant (ASM is not implemented in C++) test_traces.py: irrelevant (ASM is not implemented in C++) test_user_blocking_full_denylist.py: irrelevant (ASM is not implemented in C++) test_versions.py: irrelevant (ASM is not implemented in C++) debugger/: - test_debugger.py: - Test_Debugger_Line_Probe_Snaphots: irrelevant - Test_Debugger_Method_Probe_Snaphots: irrelevant - Test_Debugger_Mix_Log_Probe: irrelevant - Test_Debugger_Probe_Statuses: irrelevant + test_debugger_exception_replay.py: + Test_Debugger_Exception_Replay: irrelevant test_debugger_expression_language.py: Test_Debugger_Expression_Language: irrelevant test_debugger_pii.py: Test_Debugger_PII_Redaction: irrelevant + test_debugger_probe_snapshot.py: + Test_Debugger_Probe_Snaphots: irrelevant + test_debugger_probe_status.py: + Test_Debugger_Probe_Statuses: irrelevant integrations/: crossed_integrations/: test_kafka.py: @@ -126,22 +136,79 @@ tests/: Test_DsmRabbitmq_TopicExchange: missing_feature Test_DsmSNS: missing_feature Test_DsmSQS: missing_feature + Test_Dsm_Manual_Checkpoint_Inter_Process: missing_feature + Test_Dsm_Manual_Checkpoint_Intra_Process: missing_feature + test_inferred_proxy.py: + Test_AWS_API_Gateway_Inferred_Span_Creation: missing_feature + test_otel_drop_in.py: + Test_Otel_Drop_In: missing_feature parametric/: - test_dynamic_configuration.py: - TestDynamicConfigHeaderTags: missing_feature + test_128_bit_traceids.py: + Test_128_Bit_Traceids: missing_feature (parametric app does not support trace/span/extract endpoint) + test_config_consistency.py: + Test_Config_Dogstatsd: missing_feature + Test_Config_RateLimit: v1.1.0 + Test_Config_Tags: missing_feature + Test_Config_TraceAgentURL: v1.1.0 + Test_Config_TraceEnabled: v1.1.0 + Test_Config_TraceLogDirectory: missing_feature + Test_Config_UnifiedServiceTagging: v1.1.0 + test_crashtracking.py: missing_feature + test_headers_b3multi.py: + Test_Headers_B3multi: missing_feature (parametric app does not support trace/span/extract endpoint) + test_headers_baggage.py: + Test_Headers_Baggage: missing_feature + test_headers_datadog.py: + Test_Headers_Datadog: missing_feature (parametric app does not support trace/span/extract endpoint) + test_headers_none.py: + Test_Headers_None: missing_feature (parametric app does not support trace/span/extract endpoint) + test_headers_precedence.py: + Test_Headers_Precedence: missing_feature (parametric app does not support trace/span/extract endpoint) + test_headers_tracecontext.py: + Test_Headers_Tracecontext: missing_feature (parametric app does not support trace/span/extract endpoint) + test_headers_tracestate_dd.py: + Test_Headers_Tracestate_DD: missing_feature (parametric app does not support trace/span/extract endpoint) test_otel_api_interoperability.py: irrelevant (library does not implement OpenTelemetry) test_otel_env_vars.py: Test_Otel_Env_Vars: missing_feature - test_otel_sdk_interoperability.py: irrelevant (library does not implement OpenTelemetry) test_otel_span_methods.py: irrelevant (library does not implement OpenTelemetry) + test_otel_span_with_baggage.py: + Test_Otel_Span_With_Baggage: missing_feature + test_parametric_endpoints.py: + Test_Parametric_DDSpan_Add_Link: missing_feature (add_link is not supported) + Test_Parametric_DDSpan_Set_Error: bug (APMAPI-778) # The expected error status is not set + Test_Parametric_DDSpan_Set_Metric: missing_feature (Tracer does not provide a public method for directly setting a span metric) + Test_Parametric_DDSpan_Set_Resource: incomplete_test_app (set_resource endpoint is not implemented) + Test_Parametric_DDSpan_Start: bug (APMAPI-778) # Cpp parametric app does not support creating a child span from a finished span + Test_Parametric_DDTrace_Baggage: missing_feature (baggage is not supported) + Test_Parametric_DDTrace_Config: incomplete_test_app (config endpoint is not implemented) + Test_Parametric_DDTrace_Crash: incomplete_test_app (crash endpoint is not implemented) + Test_Parametric_DDTrace_Current_Span: incomplete_test_app (current_span endpoint is not implemented) + Test_Parametric_DDTrace_Extract_Headers: incomplete_test_app (extract_headers endpoint is not implemented) + # cpp tracer does not support the OpenTelemetry API, otel parametric endpoints are not implemented + Test_Parametric_OtelSpan_End: missing_feature (otel api is not supported) + Test_Parametric_OtelSpan_Events: missing_feature (otel api is not supported) + Test_Parametric_OtelSpan_Is_Recording: missing_feature (otel api is not supported) + Test_Parametric_OtelSpan_Set_Attribute: missing_feature (otel api is not supported) + Test_Parametric_OtelSpan_Set_Name: missing_feature (otel api is not supported) + Test_Parametric_OtelSpan_Set_Status: missing_feature (otel api is not supported) + Test_Parametric_OtelSpan_Start: missing_feature (otel api is not supported) + Test_Parametric_Otel_Baggage: missing_feature (otel api is not supported) + Test_Parametric_Otel_Current_Span: missing_feature (otel api is not supported) + Test_Parametric_Otel_Trace_Flush: missing_feature (otel api is not supported) + test_partial_flushing.py: + Test_Partial_Flushing: missing_feature + test_sampling_delegation.py: + Test_Decisionless_Extraction: missing_feature (parametric app does not support trace/span/extract endpoint) + test_span_events.py: missing_feature test_span_links.py: missing_feature test_telemetry.py: + Test_Consistent_Configs: missing_feature Test_TelemetryInstallSignature: missing_feature Test_TelemetrySCAEnvVar: missing_feature test_tracer.py: Test_TracerSCITagging: missing_feature - test_tracer_flare.py: - TestTracerFlareV1: missing_feature + test_tracer_flare.py: missing_feature remote_config/: test_remote_configuration.py: Test_RemoteConfigurationExtraServices: missing_feature @@ -150,15 +217,46 @@ tests/: Test_RemoteConfigurationUpdateSequenceFeatures: missing_feature Test_RemoteConfigurationUpdateSequenceFeaturesNoCache: missing_feature Test_RemoteConfigurationUpdateSequenceLiveDebugging: missing_feature - Test_RemoteConfigurationUpdateSequenceLiveDebuggingNoCache: missing_feature + serverless/: + span_pointers/: + aws/: + test_s3_span_pointers.py: + Test_CopyObject: missing_feature + Test_MultipartUpload: missing_feature + Test_PutObject: missing_feature + stats/: + test_miscs.py: + Test_Miscs: missing_feature + test_stats.py: + Test_Client_Stats: missing_feature + test_config_consistency.py: + Test_Config_ClientIPHeaderEnabled_False: v0.2.2 + Test_Config_ClientIPHeader_Configured: missing_feature (DD_TRACE_CLIENT_IP_HEADER not implemented) + Test_Config_ClientIPHeader_Precedence: missing_feature (http.client_ip is not supported) + Test_Config_ClientTagQueryString_Configured: missing_feature + Test_Config_ClientTagQueryString_Empty: missing_feature (test can not capture span with the expected http.url tag) + Test_Config_HttpClientErrorStatuses_Default: missing_feature + Test_Config_HttpClientErrorStatuses_FeatureFlagCustom: missing_feature + Test_Config_HttpServerErrorStatuses_Default: missing_feature + Test_Config_HttpServerErrorStatuses_FeatureFlagCustom: missing_feature + Test_Config_IntegrationEnabled_False: missing_feature + Test_Config_IntegrationEnabled_True: missing_feature + Test_Config_ObfuscationQueryStringRegexp_Configured: missing_feature + Test_Config_ObfuscationQueryStringRegexp_Empty: missing_feature + Test_Config_UnifiedServiceTagging_CustomService: missing_feature + Test_Config_UnifiedServiceTagging_Default: missing_feature test_distributed.py: Test_DistributedHttp: missing_feature + Test_Span_Links_Flags_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) + Test_Span_Links_From_Conflicting_Contexts: missing_feature + Test_Span_Links_From_Conflicting_Contexts_Datadog_Precedence: missing_feature + Test_Span_Links_Omit_Tracestate_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) test_identify.py: irrelevant + test_ipv6.py: missing_feature (APMAPI-869) test_library_conf.py: irrelevant test_miscs.py: irrelevant - test_profiling.py: - Test_Profile: bug (No Content-Disposition, tests do not parse the content correcly) test_scrubbing.py: irrelevant + test_span_events.py: incomplete_test_app (Weblog `/add_event` not implemented) test_standard_tags.py: irrelevant test_telemetry.py: Test_Log_Generation: missing_feature diff --git a/manifests/dd_apm_inject.yml b/manifests/dd_apm_inject.yml new file mode 100644 index 00000000000..7bf0e79fc81 --- /dev/null +++ b/manifests/dd_apm_inject.yml @@ -0,0 +1,6 @@ +tests/: + docker_ssi/: + test_docker_ssi.py: + TestDockerSSIFeatures: v0.19.1 + test_docker_ssi_crash.py: + TestDockerSSICrash: v0.19.1 diff --git a/manifests/dotnet.yml b/manifests/dotnet.yml index ef8143e75a0..e3419ae5229 100644 --- a/manifests/dotnet.yml +++ b/manifests/dotnet.yml @@ -9,9 +9,13 @@ tests/: test_api_security_rc.py: Test_API_Security_RC_ASM_DD_processors: v2.50.0 Test_API_Security_RC_ASM_DD_scanners: v2.50.0 - Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: missing_feature # waf does not support it yet + Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: irrelevant (waf does not support it yet) test_apisec_sampling.py: - Test_API_Security_sampling: v2.46.0 + Test_API_Security_Sampling_Different_Endpoints: missing_feature + Test_API_Security_Sampling_Different_Paths: missing_feature + Test_API_Security_Sampling_Different_Status: missing_feature + Test_API_Security_Sampling_Rate: v2.46.0 + Test_API_Security_Sampling_With_Delay: missing_feature test_schemas.py: Test_Scanners: v2.46.0 Test_Schema_Request_Cookies: v2.46.0 @@ -25,57 +29,98 @@ tests/: Test_Schema_Response_Headers: v2.46.0 iast/: sink/: + test_code_injection.py: + TestCodeInjection: missing_feature + TestCodeInjection_StackTrace: missing_feature test_command_injection.py: TestCommandInjection: v2.28.0 + TestCommandInjection_StackTrace: missing_feature test_hardcoded_passwords.py: Test_HardcodedPasswords: missing_feature + Test_HardcodedPasswords_StackTrace: missing_feature test_hardcoded_secrets.py: Test_HardcodedSecrets: missing_feature Test_HardcodedSecretsExtended: missing_feature + Test_HardcodedSecrets_StackTrace: missing_feature test_header_injection.py: TestHeaderInjection: v2.46.0 + TestHeaderInjectionExclusionAccessControlAllow: missing_feature + TestHeaderInjectionExclusionContentEncoding: missing_feature + TestHeaderInjectionExclusionPragma: missing_feature + TestHeaderInjectionExclusionTransferEncoding: missing_feature + TestHeaderInjection_StackTrace: missing_feature test_hsts_missing_header.py: Test_HstsMissingHeader: v2.44.0 + Test_HstsMissingHeader_StackTrace: missing_feature test_insecure_auth_protocol.py: Test_InsecureAuthProtocol: v2.49.0 + Test_InsecureAuthProtocol_StackTrace: missing_feature test_insecure_cookie.py: TestInsecureCookie: v2.39.0 + TestInsecureCookieNameFilter: missing_feature + TestInsecureCookie_StackTrace: missing_feature test_ldap_injection.py: TestLDAPInjection: v2.36.0 + TestLDAPInjection_StackTrace: missing_feature test_no_httponly_cookie.py: TestNoHttponlyCookie: v2.39.0 + TestNoHttponlyCookieNameFilter: missing_feature + TestNoHttponlyCookie_StackTrace: missing_feature test_no_samesite_cookie.py: TestNoSamesiteCookie: v2.39.0 + TestNoSamesiteCookieNameFilter: missing_feature + TestNoSamesiteCookie_StackTrace: missing_feature test_nosql_mongodb_injection.py: TestNoSqlMongodbInjection: v2.47.0 + TestNoSqlMongodbInjection_StackTrace: missing_feature test_path_traversal.py: TestPathTraversal: v2.31.0 + TestPathTraversal_StackTrace: missing_feature test_reflection_injection.py: TestReflectionInjection: v2.48.0 + TestReflectionInjection_StackTrace: missing_feature test_sql_injection.py: TestSqlInjection: '*': v2.23.0 + TestSqlInjection_StackTrace: missing_feature test_ssrf.py: TestSSRF: v2.36.0 + TestSSRF_StackTrace: missing_feature + test_template_injection.py: + TestTemplateInjection: missing_feature test_trust_boundary_violation.py: Test_TrustBoundaryViolation: v2.43.0 + Test_TrustBoundaryViolation_StackTrace: missing_feature + test_untrusted_deserialization.py: + TestUntrustedDeserialization: missing_feature + TestUntrustedDeserialization_StackTrace: missing_feature test_unvalidated_redirect.py: TestUnvalidatedHeader: v2.44.0 + TestUnvalidatedHeader_StackTrace: missing_feature TestUnvalidatedRedirect: v2.44.0 + TestUnvalidatedRedirect_StackTrace: missing_feature test_unvalidated_redirect_forward.py: TestUnvalidatedForward: missing_feature + TestUnvalidatedForward_StackTrace: missing_feature test_weak_cipher.py: TestWeakCipher: v2.24.0 + TestWeakCipher_StackTrace: missing_feature test_weak_hash.py: + TestDeduplication: v2.24.0 TestWeakHash: v2.24.0 + TestWeakHash_StackTrace: missing_feature test_weak_randomness.py: TestWeakRandomness: v2.39.0 + TestWeakRandomness_StackTrace: missing_feature test_xcontent_sniffing.py: Test_XContentSniffing: missing_feature + Test_XContentSniffing_StackTrace: missing_feature test_xpath_injection.py: - TestXPathInjection: missing_feature + TestXPathInjection: v2.47.0 + TestXPathInjection_StackTrace: missing_feature test_xss.py: TestXSS: missing_feature + TestXSS_StackTrace: missing_feature source/: test_body.py: TestRequestBody: v2.39.0 @@ -102,38 +147,86 @@ tests/: TestParameterValue: v2.28.0 test_path.py: TestPath: v2.39.0 + test_path_parameter.py: + TestPathParameter: missing_feature + test_sql_row.py: + TestSqlRow: missing_feature test_uri.py: TestURI: irrelevant rasp/: + test_cmdi.py: + Test_Cmdi_BodyJson: v3.7.0 + Test_Cmdi_BodyUrlEncoded: v3.7.0 + Test_Cmdi_BodyXml: v3.7.0 + Test_Cmdi_Capability: v3.7.0 + Test_Cmdi_Mandatory_SpanTags: v3.7.0 + Test_Cmdi_Optional_SpanTags: v3.7.0 + Test_Cmdi_Rules_Version: v3.7.0 + Test_Cmdi_StackTrace: v3.7.0 + Test_Cmdi_Telemetry: v3.7.0 + Test_Cmdi_Telemetry_Variant_Tag: v3.7.0 + Test_Cmdi_UrlQuery: v3.7.0 + Test_Cmdi_Waf_Version: v3.7.0 test_lfi.py: Test_Lfi_BodyJson: v2.51.0 Test_Lfi_BodyUrlEncoded: v2.51.0 Test_Lfi_BodyXml: v2.51.0 + Test_Lfi_Capability: v3.3.0 + Test_Lfi_Mandatory_SpanTags: v2.52.0 + Test_Lfi_Optional_SpanTags: v2.52.0 + Test_Lfi_RC_CustomAction: missing_feature + Test_Lfi_Rules_Version: v3.7.0 + Test_Lfi_StackTrace: v2.51.0 + Test_Lfi_Telemetry: v2.51.0 Test_Lfi_UrlQuery: v2.51.0 - test_span_tags.py: - Test_Mandatory_SpanTags: v2.52.0 - Test_Optional_SpanTags: v2.52.0 - test_sqli.py: missing_feature + Test_Lfi_Waf_Version: v3.4.1 + test_shi.py: + Test_Shi_BodyJson: v3.2.0 + Test_Shi_BodyUrlEncoded: v3.2.0 + Test_Shi_BodyXml: v3.2.0 + Test_Shi_Capability: v3.3.0 + Test_Shi_Mandatory_SpanTags: v3.2.0 + Test_Shi_Optional_SpanTags: v3.2.0 + Test_Shi_Rules_Version: v3.5.0 + Test_Shi_StackTrace: v3.2.0 + Test_Shi_Telemetry: v3.3.0 + Test_Shi_Telemetry_Variant_Tag: v3.7.0 + Test_Shi_UrlQuery: v3.2.0 + Test_Shi_Waf_Version: v3.4.1 + test_sqli.py: + Test_Sqli_BodyJson: v2.54.0 + Test_Sqli_BodyUrlEncoded: v2.54.0 + Test_Sqli_BodyXml: v2.54.0 + Test_Sqli_Capability: v3.3.0 + Test_Sqli_Mandatory_SpanTags: v2.54.0 + Test_Sqli_Optional_SpanTags: v2.54.0 + Test_Sqli_Rules_Version: v3.5.0 + Test_Sqli_StackTrace: v2.54.0 + Test_Sqli_Telemetry: v2.54.0 + Test_Sqli_UrlQuery: v2.54.0 + Test_Sqli_Waf_Version: v3.4.1 test_ssrf.py: Test_Ssrf_BodyJson: v2.51.0 Test_Ssrf_BodyUrlEncoded: v2.51.0 Test_Ssrf_BodyXml: v2.51.0 + Test_Ssrf_Capability: v3.3.0 + Test_Ssrf_Mandatory_SpanTags: v2.51.0 + Test_Ssrf_Optional_SpanTags: v2.51.0 + Test_Ssrf_Rules_Version: v3.5.0 + Test_Ssrf_StackTrace: v2.51.0 + Test_Ssrf_Telemetry: v2.51.0 Test_Ssrf_UrlQuery: v2.51.0 - test_stack_traces.py: - Test_StackTrace: v2.51.0 + Test_Ssrf_Waf_Version: v3.4.1 waf/: test_addresses.py: Test_BodyJson: v2.8.0 Test_BodyRaw: missing_feature Test_BodyUrlEncoded: v2.7.0 Test_BodyXml: v2.8.0 - Test_ClientIP: missing_feature Test_FullGrpc: missing_feature Test_GraphQL: missing_feature Test_GrpcServerMethod: missing_feature Test_Headers: v1.28.6 - Test_Lambda: missing_feature - Test_Method: missing_feature Test_PathParams: v2.5.1 Test_ResponseStatus: v2.3.0 Test_UrlQuery: v1.28.6 @@ -166,22 +259,32 @@ tests/: Test_Scanners: v1.28.6 test_telemetry.py: Test_TelemetryMetrics: missing_feature - test_PII.py: - Test_Scrubbing: missing_feature test_alpha.py: Test_Basic: v1.28.6 test_asm_standalone.py: - Test_AppSecStandalone_UpstreamPropagation: missing_feature + Test_AppSecStandalone_UpstreamPropagation: v2.55.0 + Test_IastStandalone_UpstreamPropagation: v2.55.0 + Test_SCAStandalone_Telemetry: v2.55.0 test_automated_login_events.py: - Test_Login_Events: v2.32.0 - Test_Login_Events_Extended: v2.33.0 - Test_V2_Login_Events: missing_feature - Test_V2_Login_Events_Anon: missing_feature - Test_V2_Login_Events_RC: missing_feature + Test_Login_Events: irrelevant (was v2.53.0 but will be replaced by V2) + Test_Login_Events_Extended: irrelevant (was v2.53.0 but will be replaced by V2) + Test_V2_Login_Events: v3.1.0 + Test_V2_Login_Events_Anon: v3.1.0 + Test_V2_Login_Events_RC: v3.1.0 + Test_V3_Auto_User_Instrum_Mode_Capability: missing_feature + Test_V3_Login_Events: missing_feature + Test_V3_Login_Events_Anon: missing_feature + Test_V3_Login_Events_Blocking: missing_feature + Test_V3_Login_Events_RC: missing_feature + test_automated_user_and_session_tracking.py: + Test_Automated_Session_Blocking: missing_feature + Test_Automated_User_Blocking: missing_feature + Test_Automated_User_Tracking: missing_feature test_blocking_addresses.py: - Test_BlockingAddresses: v2.27.0 Test_BlockingGraphqlResolvers: missing_feature + Test_Blocking_client_ip: v2.27.0 Test_Blocking_request_body: v2.29.0 + Test_Blocking_request_body_multipart: missing_feature Test_Blocking_request_cookies: v2.29.0 Test_Blocking_request_headers: v2.29.0 Test_Blocking_request_method: v2.29.0 @@ -190,29 +293,42 @@ tests/: Test_Blocking_request_uri: v2.32.0 Test_Blocking_response_headers: v2.32.0 Test_Blocking_response_status: v2.32.0 - Test_Suspicious_Request_Blocking: missing_feature (v2.29.0, but test is not implemented) + Test_Blocking_user_id: v2.27.0 + Test_Suspicious_Request_Blocking: v3.2.0 test_client_ip.py: Test_StandardTagsClientIp: v2.20.0 - test_conf.py: - Test_RuleSet_1_3_1: v2.7.0 - Test_StaticRuleSet: v1.29.0 test_customconf.py: Test_NoLimitOnWafRules: v2.4.4 test_event_tracking.py: Test_CustomEvent: v2.27.0 Test_UserLoginFailureEvent: v2.27.0 Test_UserLoginSuccessEvent: v2.27.0 + test_fingerprinting.py: + Test_Fingerprinting_Endpoint: v3.4.0 + Test_Fingerprinting_Endpoint_Capability: v3.4.0 + Test_Fingerprinting_Header_And_Network: v3.4.0 + Test_Fingerprinting_Header_Capability: v3.4.0 + Test_Fingerprinting_Network_Capability: v3.4.0 + Test_Fingerprinting_Session: missing_feature + Test_Fingerprinting_Session_Capability: v3.4.0 test_identify.py: Test_Basic: v2.7.0 test_ip_blocking_full_denylist.py: Test_AppSecIPBlockingFullDenylist: v2.16.0 test_logs.py: Test_StandardizationBlockMode: missing_feature + test_metastruct.py: + Test_SecurityEvents_Appsec_Metastruct_Disabled: v3.7.0 + Test_SecurityEvents_Appsec_Metastruct_Enabled: v3.7.0 + Test_SecurityEvents_Iast_Metastruct_Disabled: v3.7.0 + Test_SecurityEvents_Iast_Metastruct_Enabled: v3.7.0 test_rate_limiter.py: Test_Main: v2.6.0 + test_remote_config_rule_changes.py: + Test_BlockingActionChangesWithRemoteConfig: v3.4.0 + Test_UpdateRuleFileWithRemoteConfig: v3.5.0 test_reports.py: Test_ExtraTagsFromRule: v2.34.0 - Test_HttpClientIP: v1.30.0 Test_Info: v2.0.0 Test_RequestHeaders: v1.30.0 Test_StatusCode: v1.28.6 @@ -220,28 +336,31 @@ tests/: Test_AppSecRequestBlocking: v2.25.0 test_runtime_activation.py: Test_RuntimeActivation: v2.16.0 + Test_RuntimeDeactivation: v2.16.0 test_shell_execution.py: Test_ShellExecution: missing_feature + test_suspicious_attacker_blocking.py: + Test_Suspicious_Attacker_Blocking: v3.4.0 test_traces.py: Test_AppSecEventSpanTags: v1.29.0 Test_AppSecObfuscator: v2.7.0 Test_CollectDefaultRequestHeader: missing_feature Test_CollectRespondHeaders: v2.5.1 - Test_DistributedTraceInfo: missing_feature (test not implemented) Test_ExternalWafRequestsIdentification: v2.50.0 Test_RetainTraces: v1.29.0 test_user_blocking_full_denylist.py: Test_UserBlocking_FullDenylist: v2.30.0 debugger/: - test_debugger.py: - Test_Debugger_Line_Probe_Snaphots: v2.53.0 - Test_Debugger_Method_Probe_Snaphots: v2.53.0 - Test_Debugger_Mix_Log_Probe: v2.53.0 - Test_Debugger_Probe_Statuses: v2.53.0 + test_debugger_exception_replay.py: + Test_Debugger_Exception_Replay: v2.50.0 test_debugger_expression_language.py: Test_Debugger_Expression_Language: v2.50.0 test_debugger_pii.py: Test_Debugger_PII_Redaction: v2.50.0 + test_debugger_probe_snapshot.py: + Test_Debugger_Probe_Snaphots: v2.53.0 + test_debugger_probe_status.py: + Test_Debugger_Probe_Statuses: v2.53.0 integrations/: crossed_integrations/: test_kafka.py: @@ -274,24 +393,55 @@ tests/: Test_DsmRabbitmq_TopicExchange: missing_feature Test_DsmSNS: missing_feature Test_DsmSQS: v2.48.0 + Test_Dsm_Manual_Checkpoint_Inter_Process: missing_feature + Test_Dsm_Manual_Checkpoint_Intra_Process: missing_feature + test_inferred_proxy.py: + Test_AWS_API_Gateway_Inferred_Span_Creation: missing_feature + test_otel_drop_in.py: + Test_Otel_Drop_In: missing_feature + k8s_lib_injection/: + test_k8s_manual_inject.py: + TestAdmisionControllerProfiling: missing_feature parametric/: + test_config_consistency.py: + Test_Config_Dogstatsd: missing_feature (does not support hostname) + Test_Config_RateLimit: v3.4.1 + Test_Config_Tags: missing_feature + Test_Config_TraceAgentURL: v3.4.1 + Test_Config_TraceEnabled: v3.3.0 + Test_Config_TraceLogDirectory: v3.3.0 + Test_Config_UnifiedServiceTagging: v3.3.0 + test_crashtracking.py: + Test_Crashtracking: v3.2.0 test_dynamic_configuration.py: - TestDynamicConfigHeaderTags: missing_feature TestDynamicConfigSamplingRules: v2.53.2 TestDynamicConfigTracingEnabled: v2.49.0 TestDynamicConfigV1: v2.33.0 TestDynamicConfigV1_ServiceTargets: missing_feature TestDynamicConfigV2: v2.44.0 + test_headers_baggage.py: + Test_Headers_Baggage: missing_feature test_otel_api_interoperability.py: missing_feature test_otel_env_vars.py: Test_Otel_Env_Vars: v2.53.0 - test_otel_sdk_interoperability.py: missing_feature - test_otel_span_with_w3c.py: - Test_Otel_Span_With_W3c: v2.42.0 + test_otel_span_with_baggage.py: + Test_Otel_Span_With_Baggage: missing_feature test_otel_tracer.py: Test_Otel_Tracer: v2.8.0 + test_parametric_endpoints.py: + Test_Parametric_DDSpan_Add_Link: incomplete_test_app (add_link parametric endpoint is not implemented) + Test_Parametric_DDSpan_Set_Error: bug (APMAPI-778) # Set error endpoint does not set the error.type tag on spans + Test_Parametric_DDSpan_Set_Resource: incomplete_test_app (set_resource parametric endpoint is not implemented) + Test_Parametric_DDTrace_Baggage: incomplete_test_app (baggage endpoints are not implemented) + Test_Parametric_DDTrace_Current_Span: incomplete_test_app (current span endpoint is not implemented) + Test_Parametric_OtelSpan_Is_Recording: bug (APMAPI-778) # parametric endpoint attempts to retrieve spans by the `id` instead of `span_id` + Test_Parametric_OtelSpan_Set_Name: bug (APMAPI-778) # updates the operation name of the span not the resource name + Test_Parametric_Otel_Baggage: incomplete_test_app (otel baggage endpoints are not implemented) + Test_Parametric_Otel_Current_Span: incomplete_test_app (otel current span endpoint are not implemented) + test_span_events.py: missing_feature test_span_links.py: missing_feature test_telemetry.py: + Test_Consistent_Configs: missing_feature Test_Defaults: v2.49.0 Test_Environment: v2.49.0 Test_TelemetryInstallSignature: v2.45.0 @@ -305,10 +455,7 @@ tests/: Test_Trace_Sampling_Tags_Feb2024_Revision: v2.48.0 Test_Trace_Sampling_With_W3C: v2.46.0 test_tracer.py: - # The dotnet parametric app generates trace chunks in a way that differs from the other languages - # This causes the sci tests to fail. Before enabling these tests we must ensure that the first span in the - # trace chunk is always the local root span. - Test_TracerSCITagging: missing_feature + Test_TracerSCITagging: v2.48.0 test_tracer_flare.py: TestTracerFlareV1: v2.48.0 remote_config/: @@ -319,32 +466,66 @@ tests/: Test_RemoteConfigurationUpdateSequenceFeatures: v2.15.0 Test_RemoteConfigurationUpdateSequenceFeaturesNoCache: irrelevant (cache is implemented) Test_RemoteConfigurationUpdateSequenceLiveDebugging: v2.15.0 - Test_RemoteConfigurationUpdateSequenceLiveDebuggingNoCache: irrelevant (cache is implemented) + serverless/: + span_pointers/: + aws/: + test_s3_span_pointers.py: + Test_CopyObject: missing_feature + Test_MultipartUpload: missing_feature + Test_PutObject: missing_feature + stats/: + test_miscs.py: + Test_Miscs: missing_feature + test_config_consistency.py: + Test_Config_ClientIPHeaderEnabled_False: v3.6.1 + Test_Config_ClientIPHeader_Configured: v3.4.1 + Test_Config_ClientIPHeader_Precedence: v3.4.1 + Test_Config_ClientTagQueryString_Configured: missing_feature (configuration DNE) + Test_Config_ClientTagQueryString_Empty: v3.5.0 + Test_Config_HttpClientErrorStatuses_Default: v3.5.0 + Test_Config_HttpClientErrorStatuses_FeatureFlagCustom: v3.5.0 + Test_Config_HttpServerErrorStatuses_Default: v3.5.0 + Test_Config_HttpServerErrorStatuses_FeatureFlagCustom: v3.5.0 + Test_Config_IntegrationEnabled_False: v3.5.0 + Test_Config_IntegrationEnabled_True: v3.5.0 + Test_Config_ObfuscationQueryStringRegexp_Configured: v3.4.1 + Test_Config_ObfuscationQueryStringRegexp_Empty: v3.4.1 + Test_Config_UnifiedServiceTagging_CustomService: v3.3.0 + Test_Config_UnifiedServiceTagging_Default: v3.3.0 test_data_integrity.py: Test_LibraryHeaders: v2.46.0 test_distributed.py: Test_DistributedHttp: missing_feature + Test_Span_Links_Flags_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) + Test_Span_Links_From_Conflicting_Contexts: missing_feature + Test_Span_Links_From_Conflicting_Contexts_Datadog_Precedence: missing_feature + Test_Span_Links_Omit_Tracestate_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) test_identify.py: Test_Basic: v2.7.0 Test_Propagate: v2.27.0 Test_Propagate_Legacy: v2.26.0 + test_ipv6.py: missing_feature (APMAPI-869) test_library_conf.py: Test_HeaderTags: v2.27.0 Test_HeaderTags_Colon_Leading: v2.1.0 - Test_HeaderTags_Colon_Trailing: bug (AIT-8600) + Test_HeaderTags_Colon_Trailing: v3.0.0 + Test_HeaderTags_DynamicConfig: missing_feature Test_HeaderTags_Long: v2.1.0 Test_HeaderTags_Short: v2.1.0 Test_HeaderTags_Whitespace_Header: v2.1.0 - Test_HeaderTags_Whitespace_Tag: bug (AIT-8308) + Test_HeaderTags_Whitespace_Tag: v3.0.0 Test_HeaderTags_Whitespace_Val_Long: v2.1.0 Test_HeaderTags_Whitespace_Val_Short: v2.1.0 test_profiling.py: - Test_Profile: missing_feature (Not receiving profiles) + Test_Profile: + "*": v1.0 # real version not known + uds: missing_feature (to be confirmed) test_scrubbing.py: Test_UrlField: v2.29.0 Test_UrlQuery: v2.13.0 test_semantic_conventions.py: Test_MetricsStandardTags: v2.6.0 + test_span_events.py: incomplete_test_app (Weblog `/add_event` not implemented) test_standard_tags.py: Test_StandardTagsClientIp: v2.26.0 Test_StandardTagsMethod: v2.0.0 diff --git a/manifests/golang.yml b/manifests/golang.yml index 0dded100193..c6f5de78b61 100644 --- a/manifests/golang.yml +++ b/manifests/golang.yml @@ -1,4 +1,5 @@ tests/: + apm_tracing_e2e/: test_otel.py: Test_Otel_Span: @@ -13,83 +14,122 @@ tests/: test_api_security_rc.py: Test_API_Security_RC_ASM_DD_processors: missing_feature Test_API_Security_RC_ASM_DD_scanners: missing_feature - Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: missing_feature # waf does not support it yet + Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: irrelevant (waf does not support it yet) test_apisec_sampling.py: - Test_API_Security_sampling: - '*': v1.60.0-dev + Test_API_Security_Sampling_Different_Endpoints: missing_feature + Test_API_Security_Sampling_Different_Paths: missing_feature + Test_API_Security_Sampling_Different_Status: missing_feature + Test_API_Security_Sampling_Rate: + '*': v1.60.0 net-http: irrelevant (net-http doesn't handle path params) + Test_API_Security_Sampling_With_Delay: missing_feature test_schemas.py: Test_Scanners: missing_feature - Test_Schema_Request_Cookies: - '*': v1.60.0-dev - net-http: irrelevant (net-http doesn't handle path params) - Test_Schema_Request_FormUrlEncoded_Body: missing_feature - Test_Schema_Request_Headers: - '*': v1.60.0-dev - net-http: irrelevant (net-http doesn't handle path params) - Test_Schema_Request_Json_Body: missing_feature + Test_Schema_Request_Cookies: v1.60.0 + Test_Schema_Request_FormUrlEncoded_Body: v1.60.0 + Test_Schema_Request_Headers: v1.60.0 + Test_Schema_Request_Json_Body: v1.60.0 Test_Schema_Request_Path_Parameters: - '*': v1.60.0-dev - net-http: irrelevant (net-http doesn't handle path params) - Test_Schema_Request_Query_Parameters: - '*': v1.60.0-dev - net-http: irrelevant (net-http doesn't handle path params) + '*': v1.60.0 + net-http: irrelevant (net-http cannot list path params) + Test_Schema_Request_Query_Parameters: v1.60.0 Test_Schema_Response_Body: missing_feature Test_Schema_Response_Body_env_var: missing_feature - Test_Schema_Response_Headers: missing_feature + Test_Schema_Response_Headers: v1.60.0 iast/: sink/: + test_code_injection.py: + TestCodeInjection: missing_feature + TestCodeInjection_StackTrace: missing_feature test_command_injection.py: TestCommandInjection: missing_feature + TestCommandInjection_StackTrace: missing_feature test_hardcoded_passwords.py: Test_HardcodedPasswords: missing_feature + Test_HardcodedPasswords_StackTrace: missing_feature test_hardcoded_secrets.py: Test_HardcodedSecrets: missing_feature Test_HardcodedSecretsExtended: missing_feature + Test_HardcodedSecrets_StackTrace: missing_feature test_header_injection.py: TestHeaderInjection: missing_feature + TestHeaderInjectionExclusionAccessControlAllow: missing_feature + TestHeaderInjectionExclusionContentEncoding: missing_feature + TestHeaderInjectionExclusionPragma: missing_feature + TestHeaderInjectionExclusionTransferEncoding: missing_feature + TestHeaderInjection_StackTrace: missing_feature test_hsts_missing_header.py: Test_HstsMissingHeader: missing_feature + Test_HstsMissingHeader_StackTrace: missing_feature test_insecure_auth_protocol.py: Test_InsecureAuthProtocol: missing_feature + Test_InsecureAuthProtocol_StackTrace: missing_feature test_insecure_cookie.py: TestInsecureCookie: missing_feature + TestInsecureCookieNameFilter: missing_feature + TestInsecureCookie_StackTrace: missing_feature test_ldap_injection.py: TestLDAPInjection: missing_feature + TestLDAPInjection_StackTrace: missing_feature test_no_httponly_cookie.py: TestNoHttponlyCookie: missing_feature + TestNoHttponlyCookieNameFilter: missing_feature + TestNoHttponlyCookie_StackTrace: missing_feature test_no_samesite_cookie.py: TestNoSamesiteCookie: missing_feature + TestNoSamesiteCookieNameFilter: missing_feature + TestNoSamesiteCookie_StackTrace: missing_feature test_nosql_mongodb_injection.py: TestNoSqlMongodbInjection: missing_feature + TestNoSqlMongodbInjection_StackTrace: missing_feature test_path_traversal.py: TestPathTraversal: missing_feature + TestPathTraversal_StackTrace: missing_feature test_reflection_injection.py: TestReflectionInjection: missing_feature + TestReflectionInjection_StackTrace: missing_feature test_sql_injection.py: TestSqlInjection: missing_feature + TestSqlInjection_StackTrace: missing_feature test_ssrf.py: TestSSRF: missing_feature + TestSSRF_StackTrace: missing_feature + test_template_injection.py: + TestTemplateInjection: missing_feature test_trust_boundary_violation.py: Test_TrustBoundaryViolation: missing_feature + Test_TrustBoundaryViolation_StackTrace: missing_feature + test_untrusted_deserialization.py: + TestUntrustedDeserialization: missing_feature + TestUntrustedDeserialization_StackTrace: missing_feature test_unvalidated_redirect.py: TestUnvalidatedHeader: missing_feature + TestUnvalidatedHeader_StackTrace: missing_feature TestUnvalidatedRedirect: missing_feature + TestUnvalidatedRedirect_StackTrace: missing_feature test_unvalidated_redirect_forward.py: TestUnvalidatedForward: missing_feature + TestUnvalidatedForward_StackTrace: missing_feature test_weak_cipher.py: TestWeakCipher: missing_feature + TestWeakCipher_StackTrace: missing_feature test_weak_hash.py: + TestDeduplication: missing_feature TestWeakHash: missing_feature + TestWeakHash_StackTrace: missing_feature test_weak_randomness.py: TestWeakRandomness: missing_feature + TestWeakRandomness_StackTrace: missing_feature test_xcontent_sniffing.py: Test_XContentSniffing: missing_feature + Test_XContentSniffing_StackTrace: missing_feature test_xpath_injection.py: TestXPathInjection: missing_feature + TestXPathInjection_StackTrace: missing_feature test_xss.py: TestXSS: '*': missing_feature + TestXSS_StackTrace: missing_feature source/: test_body.py: TestRequestBody: missing_feature @@ -115,29 +155,46 @@ tests/: TestParameterValue: missing_feature test_path.py: TestPath: missing_feature + test_path_parameter.py: + TestPathParameter: missing_feature + test_sql_row.py: + TestSqlRow: missing_feature test_uri.py: TestURI: missing_feature rasp/: + test_cmdi.py: missing_feature test_lfi.py: missing_feature - test_span_tags.py: missing_feature + test_shi.py: irrelevant (there is no equivalent to system(3) in go) test_sqli.py: - Test_Sqli_BodyJson: v1.66.0-dev - Test_Sqli_BodyUrlEncoded: v1.66.0-dev - Test_Sqli_BodyXml: v1.66.0-dev - Test_Sqli_UrlQuery: v1.66.0-dev + Test_Sqli_BodyJson: v1.66.0 + Test_Sqli_BodyUrlEncoded: v1.66.0 + Test_Sqli_BodyXml: v1.66.0 + Test_Sqli_Capability: v1.69.0 + Test_Sqli_Mandatory_SpanTags: v1.69.0 + Test_Sqli_Optional_SpanTags: missing_feature + Test_Sqli_Rules_Version: missing_feature + Test_Sqli_StackTrace: v1.66.0 + Test_Sqli_Telemetry: missing_feature + Test_Sqli_UrlQuery: v1.66.0 + Test_Sqli_Waf_Version: missing_feature test_ssrf.py: - Test_Ssrf_BodyJson: v1.65.1-rc.1 - Test_Ssrf_BodyUrlEncoded: v1.65.1-rc.1 - Test_Ssrf_BodyXml: v1.65.1-rc.1 - Test_Ssrf_UrlQuery: v1.65.1-rc.1 - test_stack_traces.py: missing_feature + Test_Ssrf_BodyJson: v1.65.1 + Test_Ssrf_BodyUrlEncoded: v1.65.1 + Test_Ssrf_BodyXml: v1.65.1 + Test_Ssrf_Capability: v1.69.0 + Test_Ssrf_Mandatory_SpanTags: v1.69.0 + Test_Ssrf_Optional_SpanTags: missing_feature + Test_Ssrf_Rules_Version: missing_feature + Test_Ssrf_StackTrace: v1.65.1 + Test_Ssrf_Telemetry: missing_feature + Test_Ssrf_UrlQuery: v1.65.1 + Test_Ssrf_Waf_Version: missing_feature waf/: test_addresses.py: Test_BodyJson: v1.37.0 Test_BodyRaw: missing_feature Test_BodyUrlEncoded: v1.37.0 Test_BodyXml: v1.37.0 - Test_ClientIP: missing_feature Test_Cookies: '*': v1.34.0 chi: v1.36.0 @@ -151,8 +208,6 @@ tests/: chi: v1.36.0 echo: v1.36.0 gin: v1.37.0 - Test_Lambda: missing_feature - Test_Method: missing_feature Test_PathParams: '*': v1.36.0 gin: v1.37.0 @@ -241,8 +296,6 @@ tests/: gin: v1.37.0 test_telemetry.py: Test_TelemetryMetrics: missing_feature - test_PII.py: - Test_Scrubbing: missing_feature test_alpha.py: Test_Basic: '*': v1.34.0 @@ -250,17 +303,29 @@ tests/: echo: v1.36.0 gin: v1.37.0 test_asm_standalone.py: - Test_AppSecStandalone_UpstreamPropagation: missing_feature + Test_AppSecStandalone_UpstreamPropagation: v1.72.0-dev + Test_IastStandalone_UpstreamPropagation: missing_feature + Test_SCAStandalone_Telemetry: missing_feature test_automated_login_events.py: Test_Login_Events: missing_feature Test_Login_Events_Extended: missing_feature Test_V2_Login_Events: missing_feature Test_V2_Login_Events_Anon: missing_feature Test_V2_Login_Events_RC: missing_feature + Test_V3_Auto_User_Instrum_Mode_Capability: missing_feature + Test_V3_Login_Events: missing_feature + Test_V3_Login_Events_Anon: missing_feature + Test_V3_Login_Events_Blocking: missing_feature + Test_V3_Login_Events_RC: missing_feature + test_automated_user_and_session_tracking.py: + Test_Automated_Session_Blocking: missing_feature + Test_Automated_User_Blocking: missing_feature + Test_Automated_User_Tracking: missing_feature test_blocking_addresses.py: - Test_BlockingAddresses: v1.51.0 Test_BlockingGraphqlResolvers: missing_feature + Test_Blocking_client_ip: v1.51.0 Test_Blocking_request_body: missing_feature + Test_Blocking_request_body_multipart: irrelevant (Body blocking happens through SDK) Test_Blocking_request_cookies: '*': v1.51.0 net-http: irrelevant @@ -281,17 +346,24 @@ tests/: net-http: irrelevant Test_Blocking_response_headers: missing_feature Test_Blocking_response_status: missing_feature + Test_Blocking_user_id: v1.51.0 Test_Suspicious_Request_Blocking: missing_feature test_client_ip.py: Test_StandardTagsClientIp: v1.44.1 - test_conf.py: - Test_RuleSet_1_3_1: v1.38.0 test_customconf.py: Test_NoLimitOnWafRules: v1.37.0 test_event_tracking.py: Test_CustomEvent: v1.47.0 Test_UserLoginFailureEvent: v1.47.0 Test_UserLoginSuccessEvent: v1.47.0 + test_fingerprinting.py: + Test_Fingerprinting_Endpoint: v1.69.0 + Test_Fingerprinting_Endpoint_Capability: v1.69.0 + Test_Fingerprinting_Header_And_Network: v1.69.0 + Test_Fingerprinting_Header_Capability: v1.69.0 + Test_Fingerprinting_Network_Capability: v1.69.0 + Test_Fingerprinting_Session: v1.69.0 + Test_Fingerprinting_Session_Capability: v1.69.0 test_identify.py: Test_Basic: v1.37.0 test_ip_blocking_full_denylist.py: @@ -300,14 +372,17 @@ tests/: test_logs.py: Test_Standardization: missing_feature Test_StandardizationBlockMode: missing_feature + test_metastruct.py: + Test_SecurityEvents_Appsec_Metastruct_Disabled: irrelevant (no fallback will be implemented) + Test_SecurityEvents_Appsec_Metastruct_Enabled: missing_feature + Test_SecurityEvents_Iast_Metastruct_Disabled: irrelevant (no fallback will be implemented) + Test_SecurityEvents_Iast_Metastruct_Enabled: missing_feature + test_remote_config_rule_changes.py: + Test_BlockingActionChangesWithRemoteConfig: v1.69.0 + Test_UpdateRuleFileWithRemoteConfig: bug (APPSEC-55377) test_reports.py: - Test_ExtraTagsFromRule: + Test_ExtraTagsFromRule: '*': v1.62.0 - Test_HttpClientIP: - '*': v1.34.0 - chi: v1.36.0 - echo: v1.36.0 - gin: v1.37.0 Test_Info: '*': v1.34.0 chi: v1.36.0 @@ -324,9 +399,12 @@ tests/: test_request_blocking.py: Test_AppSecRequestBlocking: v1.50.0-rc.1 test_runtime_activation.py: - Test_RuntimeActivation: missing_feature + Test_RuntimeActivation: v1.69.0 + Test_RuntimeDeactivation: v1.69.0 test_shell_execution.py: Test_ShellExecution: missing_feature + test_suspicious_attacker_blocking.py: + Test_Suspicious_Attacker_Blocking: v1.69.0 test_traces.py: Test_AppSecEventSpanTags: '*': v1.36.0 @@ -338,8 +416,7 @@ tests/: Test_CollectRespondHeaders: '*': v1.36.2 gin: v1.37.0 - Test_DistributedTraceInfo: missing_feature (test not implemented) - Test_ExternalWafRequestsIdentification: v1.63.0-dev + Test_ExternalWafRequestsIdentification: v1.63.0 Test_RetainTraces: '*': v1.36.0 gin: v1.37.0 @@ -350,15 +427,16 @@ tests/: '*': v1.36.0 gin: v1.37.0 debugger/: - test_debugger.py: - Test_Debugger_Line_Probe_Snaphots: missing_feature (feature not implented) - Test_Debugger_Method_Probe_Snaphots: missing_feature (feature not implented) - Test_Debugger_Mix_Log_Probe: missing_feature (feature not implented) - Test_Debugger_Probe_Statuses: missing_feature (feature not implented) + test_debugger_exception_replay.py: + Test_Debugger_Exception_Replay: missing_feature (feature not implented) test_debugger_expression_language.py: Test_Debugger_Expression_Language: missing_feature (feature not implented) test_debugger_pii.py: Test_Debugger_PII_Redaction: missing_feature (feature not implented) + test_debugger_probe_snapshot.py: + Test_Debugger_Probe_Snaphots: missing_feature (feature not implented) + test_debugger_probe_status.py: + Test_Debugger_Probe_Statuses: missing_feature (feature not implented) integrations/: crossed_integrations/: test_kafka.py: @@ -391,10 +469,10 @@ tests/: test_dbm.py: Test_Dbm: missing_feature test_dsm.py: - Test_DsmContext_Extraction_Base64: + Test_DsmContext_Extraction_Base64: "*": irrelevant net-http: v0.1 # real version unknown - Test_DsmContext_Injection_Base64: + Test_DsmContext_Injection_Base64: "*": irrelevant net-http: v0.1 # real version unknown Test_DsmHttp: missing_feature @@ -404,7 +482,7 @@ tests/: Test_DsmKinesis: "*": irrelevant net-http: missing_feature (Endpoint not implemented) - Test_DsmRabbitmq: + Test_DsmRabbitmq: "*": irrelevant net-http: missing_feature (Endpoint not implemented) Test_DsmRabbitmq_FanoutExchange: @@ -419,20 +497,53 @@ tests/: Test_DsmSQS: "*": irrelevant net-http: missing_feature (Endpoint not implemented) + Test_Dsm_Manual_Checkpoint_Inter_Process: + "*": irrelevant + net-http: missing_feature (Endpoint not implemented) + Test_Dsm_Manual_Checkpoint_Intra_Process: + "*": irrelevant + net-http: missing_feature (Endpoint not implemented) + test_inferred_proxy.py: + Test_AWS_API_Gateway_Inferred_Span_Creation: missing_feature + test_otel_drop_in.py: + Test_Otel_Drop_In: missing_feature parametric/: + test_config_consistency.py: + Test_Config_Dogstatsd: missing_feature + Test_Config_RateLimit: v1.67.0 + Test_Config_Tags: v1.70.1 + Test_Config_TraceAgentURL: v1.70.0 + Test_Config_TraceEnabled: v1.67.0 + Test_Config_TraceLogDirectory: v1.70.0 + Test_Config_UnifiedServiceTagging: bug (APMAPI-746) + test_crashtracking.py: missing_feature test_dynamic_configuration.py: - TestDynamicConfigHeaderTags: missing_feature - TestDynamicConfigSamplingRules: v1.64.0-dev + TestDynamicConfigSamplingRules: v1.64.0 TestDynamicConfigTracingEnabled: v1.61.0 TestDynamicConfigV1: v1.59.0 TestDynamicConfigV1_ServiceTargets: v1.59.0 TestDynamicConfigV2: v1.59.0 + test_headers_baggage.py: + Test_Headers_Baggage: missing_feature test_otel_api_interoperability.py: missing_feature test_otel_env_vars.py: - Test_Otel_Env_Vars: missing_feature - test_otel_sdk_interoperability.py: missing_feature + Test_Otel_Env_Vars: v1.66.0 + test_otel_span_with_baggage.py: + Test_Otel_Span_With_Baggage: missing_feature + test_parametric_endpoints.py: + Test_Parametric_DDSpan_Add_Link: missing_feature (add_link endpoint is not implemented) + Test_Parametric_DDSpan_Set_Resource: missing_feature (does not support setting a resource name after span creation) + Test_Parametric_DDTrace_Baggage: missing_feature (baggage endpoints are not implemented) + Test_Parametric_DDTrace_Crash: missing_feature (crash endpoint is not implemented) + Test_Parametric_DDTrace_Current_Span: missing_feature (spans are stored in a local context, there is no global current span in the go tracer) + Test_Parametric_OtelSpan_Set_Name: bug (APMAPI-778) # The set_name endpoint should set the resouce name (not the span name) + Test_Parametric_OtelSpan_Start: bug (APMAPI-778) # String attributes are incorrectly stored/serialized in a list + Test_Parametric_Otel_Baggage: missing_feature (otel baggage is not supported) + Test_Parametric_Otel_Current_Span: missing_feature (otel current span endpoint is not defined) + test_span_events.py: missing_feature test_span_links.py: missing_feature test_telemetry.py: + Test_Consistent_Configs: missing_feature (APMAPI-745) Test_Defaults: missing_feature Test_Environment: missing_feature Test_TelemetryInstallSignature: missing_feature @@ -440,10 +551,10 @@ tests/: test_trace_sampling.py: Test_Trace_Sampling_Basic: v1.37.0 # TODO what is the earliest version? Test_Trace_Sampling_Globs: v1.60.0 - Test_Trace_Sampling_Globs_Feb2024_Revision: v1.64.0-dev + Test_Trace_Sampling_Globs_Feb2024_Revision: v1.64.0 Test_Trace_Sampling_Resource: v1.60.0 Test_Trace_Sampling_Tags: v1.60.0 - Test_Trace_Sampling_Tags_Feb2024_Revision: v1.64.0-dev + Test_Trace_Sampling_Tags_Feb2024_Revision: v1.64.0 test_tracer.py: Test_TracerSCITagging: v1.48.0 test_tracer_flare.py: @@ -456,11 +567,41 @@ tests/: Test_RemoteConfigurationUpdateSequenceFeatures: v1.44.1 Test_RemoteConfigurationUpdateSequenceFeaturesNoCache: irrelevant (cache is implemented) Test_RemoteConfigurationUpdateSequenceLiveDebugging: missing_feature - Test_RemoteConfigurationUpdateSequenceLiveDebuggingNoCache: irrelevant (cache is implemented) + serverless/: + span_pointers/: + aws/: + test_s3_span_pointers.py: + Test_CopyObject: missing_feature + Test_MultipartUpload: missing_feature + Test_PutObject: missing_feature + test_config_consistency.py: + Test_Config_ClientIPHeaderEnabled_False: v1.70.1 + Test_Config_ClientIPHeader_Configured: v1.60.0 + Test_Config_ClientIPHeader_Precedence: v1.69.0 + Test_Config_ClientTagQueryString_Configured: missing_feature (supports DD_TRACE_HTTP_URL_QUERY_STRING_DISABLED) + Test_Config_ClientTagQueryString_Empty: bug (APMAPI-966) # DD_TRACE_HTTP_CLIENT_TAG_QUERY_STRING is disabled by default + Test_Config_HttpClientErrorStatuses_Default: v1.69.0 + Test_Config_HttpClientErrorStatuses_FeatureFlagCustom: v1.69.0 + Test_Config_HttpServerErrorStatuses_Default: v1.67.0 + Test_Config_HttpServerErrorStatuses_FeatureFlagCustom: + "*": v1.69.0 + echo: missing_feature + uds-echo: missing_feature + Test_Config_IntegrationEnabled_False: irrelevant (not applicable to Go because of how they do auto instrumentation) + Test_Config_IntegrationEnabled_True: irrelevant (not applicable to Go because of how they do auto instrumentation) + Test_Config_ObfuscationQueryStringRegexp_Configured: v1.67.0 + Test_Config_ObfuscationQueryStringRegexp_Empty: v1.67.0 + Test_Config_UnifiedServiceTagging_CustomService: v1.67.0 + Test_Config_UnifiedServiceTagging_Default: v1.67.0 test_data_integrity.py: Test_LibraryHeaders: v1.60.0.dev0 test_distributed.py: Test_DistributedHttp: missing_feature + Test_Span_Links_Flags_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) + Test_Span_Links_From_Conflicting_Contexts: missing_feature + Test_Span_Links_From_Conflicting_Contexts_Datadog_Precedence: missing_feature + Test_Span_Links_Omit_Tracestate_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) + Test_Synthetics_APM_Datadog: bug (APMAPI-901) # the incoming headers are considered invalid test_identify.py: Test_Basic: v1.37.0 Test_Propagate: v1.48.0-rc.1 @@ -468,19 +609,19 @@ tests/: test_library_conf.py: Test_HeaderTags: v1.53.0 Test_HeaderTags_Colon_Leading: v1.53.0 - Test_HeaderTags_Colon_Trailing: bug (AIT-8571) + Test_HeaderTags_Colon_Trailing: v1.70.0 + Test_HeaderTags_DynamicConfig: missing_feature Test_HeaderTags_Long: v1.53.0 Test_HeaderTags_Short: v1.53.0 Test_HeaderTags_Whitespace_Header: v1.53.0 Test_HeaderTags_Whitespace_Tag: v1.53.0 Test_HeaderTags_Whitespace_Val_Long: v1.53.0 Test_HeaderTags_Whitespace_Val_Short: v1.53.0 - test_profiling.py: - Test_Profile: bug (Not receiving profiles) test_scrubbing.py: Test_UrlQuery: v1.40.0 test_semantic_conventions.py: Test_Meta: v1.45.0 + test_span_events.py: incomplete_test_app (Weblog `/add_event` not implemented) test_standard_tags.py: Test_StandardTagsClientIp: v1.46.0 Test_StandardTagsMethod: v1.39.0 diff --git a/manifests/java.yml b/manifests/java.yml index f24d6188bee..6e734419ee4 100644 --- a/manifests/java.yml +++ b/manifests/java.yml @@ -2,20 +2,33 @@ tests/: apm_tracing_e2e/: test_otel.py: Test_Otel_Span: - '*': missing_feature (/e2e_otel_span endpoint is only implemented in Java Spring Boot at the moment) - spring-boot: v0.1 # real version not known + '*': v0.1 # real version not known + akka-http: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + jersey-grizzly2: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + play: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + ratpack: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + resteasy-netty3: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + spring-boot-3-native: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + vertx3: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + vertx4: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) test_single_span.py: Test_SingleSpan: - '*': missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) - spring-boot: v0.1 # real version not known + '*': v0.1 # real version not known + akka-http: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + jersey-grizzly2: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + play: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + ratpack: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + resteasy-netty3: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + spring-boot-3-native: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + vertx3: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) + vertx4: missing_feature (/e2e_single_span endpoint is only implemented in Java Spring Boot at the moment) appsec/: api_security/: test_api_security_rc.py: Test_API_Security_RC_ASM_DD_processors: missing_feature Test_API_Security_RC_ASM_DD_scanners: missing_feature - Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: missing_feature # waf does not support it yet - test_apisec_sampling.py: - Test_API_Security_sampling: missing_feature + Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: irrelevant (waf does not support it yet) + test_apisec_sampling.py: missing_feature test_schemas.py: Test_Scanners: '*': v1.31.0 @@ -39,6 +52,9 @@ tests/: Test_Schema_Response_Headers: missing_feature iast/: sink/: + test_code_injection.py: + TestCodeInjection: missing_feature + TestCodeInjection_StackTrace: missing_feature test_command_injection.py: TestCommandInjection: '*': v1.1.0 @@ -50,8 +66,14 @@ tests/: spring-boot-3-native: missing_feature (GraalVM. Tracing support only) vertx3: v1.12.0 vertx4: v1.12.0 + TestCommandInjection_StackTrace: + '*': v1.43.0 + play: missing_feature + ratpack: missing_feature + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_hardcoded_passwords.py: Test_HardcodedPasswords: missing_feature + Test_HardcodedPasswords_StackTrace: missing_feature test_hardcoded_secrets.py: Test_HardcodedSecrets: '*': missing_feature @@ -63,6 +85,7 @@ tests/: spring-boot-wildfly: v1.29.0 uds-spring-boot: v1.29.0 Test_HardcodedSecretsExtended: missing_feature + Test_HardcodedSecrets_StackTrace: irrelevant (not expected to have a stack trace) test_header_injection.py: TestHeaderInjection: '*': missing_feature @@ -73,6 +96,19 @@ tests/: spring-boot-undertow: v1.27.0 spring-boot-wildfly: v1.27.0 uds-spring-boot: v1.27.0 + TestHeaderInjectionExclusionAccessControlAllow: missing_feature + TestHeaderInjectionExclusionContentEncoding: missing_feature + TestHeaderInjectionExclusionPragma: missing_feature + TestHeaderInjectionExclusionTransferEncoding: missing_feature + TestHeaderInjection_StackTrace: + '*': missing_feature + spring-boot: v1.43.0 + spring-boot-jetty: v1.43.0 + spring-boot-openliberty: v1.43.0 + spring-boot-payara: v1.43.0 + spring-boot-undertow: v1.43.0 + spring-boot-wildfly: v1.43.0 + uds-spring-boot: v1.43.0 test_hsts_missing_header.py: Test_HstsMissingHeader: '*': v1.20.0 @@ -85,6 +121,7 @@ tests/: spring-boot-openliberty: bug (APPSEC-51483) vertx3: missing_feature vertx4: missing_feature + Test_HstsMissingHeader_StackTrace: irrelevant (not expected to have a stack trace) test_insecure_auth_protocol.py: Test_InsecureAuthProtocol: '*': v1.30.0 @@ -92,7 +129,14 @@ tests/: play: missing_feature ratpack: missing_feature spring-boot-3-native: missing_feature (GraalVM. Tracing support only) - spring-boot-openliberty: bug (not working as expected) + spring-boot-openliberty: bug (APPSEC-54981) + Test_InsecureAuthProtocol_StackTrace: + '*': v1.43.0 + akka-http: missing_feature + play: missing_feature + ratpack: missing_feature + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-openliberty: bug (APPSEC-54981) test_insecure_cookie.py: TestInsecureCookie: '*': v1.18.0 @@ -100,6 +144,13 @@ tests/: play: missing_feature ratpack: missing_feature spring-boot-3-native: missing_feature + TestInsecureCookieNameFilter: missing_feature + TestInsecureCookie_StackTrace: + '*': v1.43.0 + akka-http: missing_feature + play: missing_feature + ratpack: missing_feature + spring-boot-3-native: missing_feature test_ldap_injection.py: TestLDAPInjection: '*': v1.3.0 @@ -111,6 +162,11 @@ tests/: spring-boot-3-native: missing_feature (GraalVM. Tracing support only) vertx3: v1.12.0 vertx4: v1.12.0 + TestLDAPInjection_StackTrace: + '*': v1.43.0 + play: missing_feature (endpoint not implemented) + ratpack: missing_feature (endpoint not implemented) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_no_httponly_cookie.py: TestNoHttponlyCookie: '*': v1.18.0 @@ -118,6 +174,13 @@ tests/: play: missing_feature ratpack: missing_feature spring-boot-3-native: missing_feature + TestNoHttponlyCookieNameFilter: missing_feature + TestNoHttponlyCookie_StackTrace: + '*': v1.43.0 + akka-http: missing_feature + play: missing_feature + ratpack: missing_feature + spring-boot-3-native: missing_feature test_no_samesite_cookie.py: TestNoSamesiteCookie: '*': v1.18.0 @@ -125,8 +188,16 @@ tests/: play: missing_feature ratpack: missing_feature spring-boot-3-native: missing_feature + TestNoSamesiteCookieNameFilter: missing_feature + TestNoSamesiteCookie_StackTrace: + '*': v1.43.0 + akka-http: missing_feature + play: missing_feature + ratpack: missing_feature + spring-boot-3-native: missing_feature test_nosql_mongodb_injection.py: TestNoSqlMongodbInjection: missing_feature + TestNoSqlMongodbInjection_StackTrace: missing_feature test_path_traversal.py: TestPathTraversal: '*': v1.1.0 @@ -137,6 +208,11 @@ tests/: resteasy-netty3: v1.11.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) vertx3: v1.12.0 + TestPathTraversal_StackTrace: + '*': v1.43.0 + play: missing_feature + ratpack: missing_feature + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_reflection_injection.py: TestReflectionInjection: '*': v1.31.0 @@ -144,6 +220,12 @@ tests/: play: missing_feature ratpack: missing_feature spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + TestReflectionInjection_StackTrace: + '*': v1.43.0 + akka-http: missing_feature + play: missing_feature + ratpack: missing_feature + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_sql_injection.py: TestSqlInjection: '*': v1.1.0 @@ -154,6 +236,11 @@ tests/: resteasy-netty3: v1.11.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) vertx3: v1.12.0 + TestSqlInjection_StackTrace: + '*': v1.43.0 + play: missing_feature + ratpack: missing_feature + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_ssrf.py: TestSSRF: '*': v1.13.0 @@ -162,6 +249,15 @@ tests/: ratpack: missing_feature (No endpoint implemented) spring-boot-3-native: missing_feature (GraalVM. Tracing support only) vertx4: missing_feature (No endpoint implemented) + TestSSRF_StackTrace: + '*': v1.43.0 + akka-http: missing_feature (No endpoint implemented) + play: missing_feature (No endpoint implemented) + ratpack: missing_feature (No endpoint implemented) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + vertx4: missing_feature (No endpoint implemented) + test_template_injection.py: + TestTemplateInjection: missing_feature test_trust_boundary_violation.py: Test_TrustBoundaryViolation: '*': v1.22.0 @@ -173,6 +269,37 @@ tests/: spring-boot-3-native: missing_feature (GraalVM. Tracing support only) vertx3: missing_feature vertx4: missing_feature + Test_TrustBoundaryViolation_StackTrace: + '*': v1.43.0 + akka-http: missing_feature + jersey-grizzly2: missing_feature + play: missing_feature + ratpack: missing_feature + resteasy-netty3: missing_feature + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + vertx3: missing_feature + vertx4: missing_feature + test_untrusted_deserialization.py: + TestUntrustedDeserialization: + '*': v1.38.0 + akka-http: missing_feature (No endpoint implemented) + jersey-grizzly2: missing_feature (No endpoint implemented) + play: missing_feature (No endpoint implemented) + ratpack: missing_feature (No endpoint implemented) + resteasy-netty3: missing_feature (No endpoint implemented) + spring-boot-3-native: missing_feature (No endpoint implemented) + vertx3: missing_feature (No endpoint implemented) + vertx4: missing_feature (No endpoint implemented) + TestUntrustedDeserialization_StackTrace: + '*': v1.43.0 + akka-http: missing_feature (No endpoint implemented) + jersey-grizzly2: missing_feature (No endpoint implemented) + play: missing_feature (No endpoint implemented) + ratpack: missing_feature (No endpoint implemented) + resteasy-netty3: missing_feature (No endpoint implemented) + spring-boot-3-native: missing_feature (No endpoint implemented) + vertx3: missing_feature (No endpoint implemented) + vertx4: missing_feature (No endpoint implemented) test_unvalidated_redirect.py: TestUnvalidatedHeader: '*': v1.15.0 @@ -183,6 +310,12 @@ tests/: spring-boot-jetty: v1.17.0 vertx3: v1.16.0 vertx4: v1.17.0 + TestUnvalidatedHeader_StackTrace: + '*': v1.43.0 + akka-http: missing_feature + play: missing_feature + ratpack: missing_feature + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) TestUnvalidatedRedirect: '*': v1.15.0 akka-http: missing_feature @@ -191,6 +324,12 @@ tests/: spring-boot-3-native: missing_feature (GraalVM. Tracing support only) spring-boot-jetty: v1.17.0 vertx4: v1.17.0 + TestUnvalidatedRedirect_StackTrace: + '*': v1.43.0 + akka-http: missing_feature + play: missing_feature + ratpack: missing_feature + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_unvalidated_redirect_forward.py: TestUnvalidatedForward: '*': v1.15.0 @@ -202,21 +341,45 @@ tests/: spring-boot-3-native: missing_feature (GraalVM. Tracing support only) vertx3: v1.16.0 vertx4: v1.17.0 + TestUnvalidatedForward_StackTrace: + '*': v1.43.0 + akka-http: irrelevant (No forward) + jersey-grizzly2: irrelevant (No forward) + play: missing_feature (No endpoint implemented) + ratpack: irrelevant (No forward) + resteasy-netty3: irrelevant (No forward) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_weak_cipher.py: TestWeakCipher: '*': v0.108.0 play: missing_feature (no endpoint) spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + TestWeakCipher_StackTrace: + '*': v1.43.0 + play: missing_feature (no endpoint) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_weak_hash.py: + TestDeduplication: + '*': v0.108.0 + play: missing_feature (no endpoint) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) TestWeakHash: '*': v0.108.0 play: missing_feature (no endpoint) spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + TestWeakHash_StackTrace: + '*': v1.43.0 + play: missing_feature (no endpoint) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_weak_randomness.py: TestWeakRandomness: '*': v1.15.0 play: missing_feature (no endpoint) spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + TestWeakRandomness_StackTrace: + '*': v1.43.0 + play: missing_feature (no endpoint) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_xcontent_sniffing.py: Test_XContentSniffing: '*': v1.22.0 @@ -226,15 +389,21 @@ tests/: ratpack: missing_feature resteasy-netty3: missing_feature spring-boot-3-native: missing_feature (GraalVM. Tracing support only) - spring-boot-openliberty: bug (not working as expected) + spring-boot-openliberty: bug (APPSEC-54981) vertx3: missing_feature vertx4: missing_feature + Test_XContentSniffing_StackTrace: irrelevant (not expected to have a stack trace) test_xpath_injection.py: TestXPathInjection: '*': v1.18.0 play: missing_feature ratpack: missing_feature spring-boot-3-native: missing_feature + TestXPathInjection_StackTrace: + '*': v1.43.0 + play: missing_feature + ratpack: missing_feature + spring-boot-3-native: missing_feature test_xss.py: TestXSS: '*': v1.19.0 @@ -246,6 +415,16 @@ tests/: spring-boot-3-native: missing_feature (GraalVM. Tracing support only) vertx3: missing_feature vertx4: missing_feature + TestXSS_StackTrace: + '*': v1.43.0 + akka-http: missing_feature + jersey-grizzly2: missing_feature + play: missing_feature + ratpack: missing_feature + resteasy-netty3: missing_feature + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + vertx3: missing_feature + vertx4: missing_feature source/: test_body.py: TestRequestBody: @@ -272,7 +451,7 @@ tests/: TestCookieValue: '*': v1.10.0 akka-http: v1.12.0 - jersey-grizzly2: bug (name field of source not set) + jersey-grizzly2: v1.41.0 play: missing_feature ratpack: missing_feature resteasy-netty3: v1.11.0 @@ -296,7 +475,7 @@ tests/: TestHeaderValue: '*': v1.3.0 akka-http: v1.12.0 - jersey-grizzly2: bug (name field of source not set) + jersey-grizzly2: v1.41.0 play: missing_feature ratpack: missing_feature resteasy-netty3: v1.11.0 @@ -350,7 +529,7 @@ tests/: TestParameterValue: '*': v1.1.0 akka-http: v1.12.0 - jersey-grizzly2: bug (name field of source not set) + jersey-grizzly2: v1.41.0 play: missing_feature ratpack: missing_feature resteasy-netty3: v1.11.0 @@ -368,6 +547,11 @@ tests/: spring-boot-3-native: missing_feature (GraalVM. Tracing support only) vertx3: missing_feature vertx4: missing_feature + test_path_parameter.py: + TestPathParameter: + '*': missing_feature + test_sql_row.py: + TestSqlRow: missing_feature test_uri.py: TestURI: '*': v1.23.0 @@ -380,11 +564,264 @@ tests/: vertx3: missing_feature vertx4: missing_feature rasp/: - test_lfi.py: missing_feature - test_span_tags.py: missing_feature - test_sqli.py: missing_feature - test_ssrf.py: missing_feature - test_stack_traces.py: missing_feature + test_cmdi.py: + Test_Cmdi_BodyJson: + '*': v1.45.0 + akka-http: missing_feature (APPSEC-56196) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx4: missing_feature (APPSEC-55785) + Test_Cmdi_BodyUrlEncoded: + '*': v1.45.0 + akka-http: missing_feature (APPSEC-56196) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Cmdi_BodyXml: + '*': v1.45.0 + akka-http: missing_feature (APPSEC-55780) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: missing_feature (APPSEC-55788) + vertx4: missing_feature (APPSEC-55786) + Test_Cmdi_Capability: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Cmdi_Mandatory_SpanTags: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Cmdi_Optional_SpanTags: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Cmdi_Rules_Version: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Cmdi_StackTrace: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Cmdi_Telemetry: + '*': v1.45.0 + akka-http: missing_feature (APPSEC-56196) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Cmdi_Telemetry_Variant_Tag: + '*': v1.45.0 + akka-http: missing_feature (APPSEC-56196) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Cmdi_UrlQuery: + '*': v1.45.0 + akka-http: missing_feature (APPSEC-56196) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Cmdi_Waf_Version: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + test_lfi.py: + Test_Lfi_BodyJson: + '*': v1.40.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx4: missing_feature (APPSEC-55785) + Test_Lfi_BodyUrlEncoded: + '*': v1.40.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Lfi_BodyXml: + '*': v1.40.0 + akka-http: missing_feature (APPSEC-55780) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: missing_feature (APPSEC-55788) + vertx4: missing_feature (APPSEC-55786) + Test_Lfi_Capability: + '*': v1.40.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Lfi_Mandatory_SpanTags: + '*': v1.40.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Lfi_Optional_SpanTags: + '*': v1.40.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Lfi_RC_CustomAction: missing_feature (APPSEC-54930) + Test_Lfi_Rules_Version: + '*': v1.43.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Lfi_StackTrace: + '*': v1.40.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Lfi_Telemetry: + '*': v1.40.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Lfi_UrlQuery: + '*': v1.40.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Lfi_Waf_Version: + '*': v1.40.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + test_shi.py: + Test_Shi_BodyJson: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx4: missing_feature (APPSEC-55785) + Test_Shi_BodyUrlEncoded: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Shi_BodyXml: + '*': v1.45.0 + akka-http: missing_feature (APPSEC-55780) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: missing_feature (APPSEC-55788) + vertx4: missing_feature (APPSEC-55786) + Test_Shi_Capability: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Shi_Mandatory_SpanTags: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Shi_Optional_SpanTags: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Shi_Rules_Version: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Shi_StackTrace: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Shi_Telemetry: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Shi_Telemetry_Variant_Tag: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Shi_UrlQuery: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + Test_Shi_Waf_Version: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + # SQLi was introduced in v1.38.0 (with RASP disabled by default, but was flaky) + test_sqli.py: + Test_Sqli_BodyJson: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx4: missing_feature (APPSEC-55785) + Test_Sqli_BodyUrlEncoded: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: v1.40.0 # issue in context propagation in 1.39.0 + vertx4: v1.40.0 # issue in context propagation in 1.39.0 + Test_Sqli_BodyXml: + '*': v1.39.0 + akka-http: missing_feature (APPSEC-55780) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: missing_feature (APPSEC-55788) + vertx4: missing_feature (APPSEC-55786) + Test_Sqli_Capability: + '*': v1.40.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Sqli_Mandatory_SpanTags: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + vertx3: v1.40.0 # issue in context propagation in 1.39.0 + vertx4: v1.40.0 # issue in context propagation in 1.39.0 + Test_Sqli_Optional_SpanTags: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + vertx3: v1.40.0 # issue in context propagation in 1.39.0 + vertx4: v1.40.0 # issue in context propagation in 1.39.0 + Test_Sqli_Rules_Version: + '*': v1.43.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Sqli_StackTrace: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: v1.40.0 # issue in context propagation in 1.39.0 + vertx4: v1.40.0 # issue in context propagation in 1.39.0 + Test_Sqli_Telemetry: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: v1.40.0 # issue in context propagation in 1.39.0 + vertx4: v1.40.0 # issue in context propagation in 1.39.0 + Test_Sqli_UrlQuery: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: v1.40.0 # issue in context propagation in 1.39.0 + vertx4: v1.40.0 # issue in context propagation in 1.39.0 + Test_Sqli_Waf_Version: + '*': v1.40.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + test_ssrf.py: + Test_Ssrf_BodyJson: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: missing_feature (APPSEC-55781) + vertx4: missing_feature (APPSEC-55781, APPSEC-55785) + Test_Ssrf_BodyUrlEncoded: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: missing_feature (APPSEC-55781) + vertx4: missing_feature (APPSEC-55781) + Test_Ssrf_BodyXml: + '*': v1.39.0 + akka-http: missing_feature (APPSEC-55780) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: missing_feature (APPSEC-55781, APPSEC-55788) + vertx4: missing_feature (APPSEC-55781, APPSEC-55786) + Test_Ssrf_Capability: + '*': v1.40.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Ssrf_Mandatory_SpanTags: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + vertx4: missing_feature (APPSEC-55781) + Test_Ssrf_Optional_SpanTags: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + vertx4: missing_feature (APPSEC-55781) + Test_Ssrf_Rules_Version: + '*': v1.43.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_Ssrf_StackTrace: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: missing_feature (APPSEC-55781) + vertx4: missing_feature (APPSEC-55781) + Test_Ssrf_Telemetry: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: missing_feature (APPSEC-55781) + vertx4: missing_feature (APPSEC-55781) + Test_Ssrf_UrlQuery: + '*': v1.39.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: missing_feature (APPSEC-54966) + vertx3: missing_feature (APPSEC-55781) + vertx4: missing_feature (APPSEC-55781) + Test_Ssrf_Waf_Version: + '*': v1.40.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) waf/: test_addresses.py: Test_BodyJson: @@ -394,8 +831,7 @@ tests/: ratpack: v0.99.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) vertx3: v0.99.0 - vertx4: bug (Capability to read body content is incomplete after vert.x - 4.0.0) + vertx4: bug (APPSEC-54983) Test_BodyRaw: '*': missing_feature akka-http: v1.22.0 @@ -416,9 +852,7 @@ tests/: ratpack: v0.99.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) vertx3: missing_feature - vertx4: bug (Capability to read body content is incomplete after vert.x - 4.0.0) - Test_ClientIP: missing_feature + vertx4: bug (APPSEC-54983) Test_Cookies: akka-http: v1.22.0 play: v1.22.0 @@ -430,8 +864,6 @@ tests/: '*': v0.87.0 akka-http: v1.22.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) - Test_Lambda: missing_feature - Test_Method: missing_feature Test_PathParams: '*': v0.95.1 akka-http: missing_feature (unclear how to implement; matching doesn't happen in one go) @@ -569,23 +1001,110 @@ tests/: '*': v1.12.0 akka-http: v1.22.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) - test_PII.py: - Test_Scrubbing: missing_feature test_alpha.py: Test_Basic: '*': v0.87.0 akka-http: v1.22.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_asm_standalone.py: - Test_AppSecStandalone_UpstreamPropagation: missing_feature + Test_AppSecStandalone_UpstreamPropagation: + '*': v1.36.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_IastStandalone_UpstreamPropagation: + '*': v1.36.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_SCAStandalone_Telemetry: + '*': v1.45.0 + akka-http: missing_feature (endpoints not implemented) + jersey-grizzly2: missing_feature (endpoints not implemented) + play: missing_feature (endpoints not implemented) + ratpack: missing_feature (endpoints not implemented) + resteasy-netty3: missing_feature (endpoints not implemented) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + vertx3: missing_feature (endpoints not implemented) + vertx4: missing_feature (endpoints not implemented) test_automated_login_events.py: - Test_Login_Events: missing_feature - Test_Login_Events_Extended: missing_feature - Test_V2_Login_Events: missing_feature - Test_V2_Login_Events_Anon: missing_feature - Test_V2_Login_Events_RC: missing_feature + Test_Login_Events: irrelevant (was v1.36.0 but will be replaced by V2) + Test_Login_Events_Extended: irrelevant (was v1.36.0 but will be replaced by V2) + Test_V2_Login_Events: irrelevant (v1.38.0, replaced by V3) + Test_V2_Login_Events_Anon: irrelevant (v1.38.0, replaced by V3) + Test_V2_Login_Events_RC: irrelevant (v1.38.0, replaced by V3) + Test_V3_Auto_User_Instrum_Mode_Capability: + '*': v1.45.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_V3_Login_Events: + '*': v1.45.0 + akka-http: missing_feature (login endpoints not implemented) + jersey-grizzly2: missing_feature (login endpoints not implemented) + play: missing_feature (login endpoints not implemented) + ratpack: missing_feature (login endpoints not implemented) + resteasy-netty3: missing_feature (login endpoints not implemented) + spring-boot-3-native: flaky (APMAPI-979) + spring-boot-openliberty: missing_feature (weblog returns error 500) + vertx3: missing_feature (login endpoints not implemented) + vertx4: missing_feature (login endpoints not implemented) + Test_V3_Login_Events_Anon: + '*': v1.45.0 + akka-http: missing_feature (login endpoints not implemented) + jersey-grizzly2: missing_feature (login endpoints not implemented) + play: missing_feature (login endpoints not implemented) + ratpack: missing_feature (login endpoints not implemented) + resteasy-netty3: missing_feature (login endpoints not implemented) + spring-boot-3-native: flaky (APMAPI-979) + spring-boot-openliberty: missing_feature (weblog returns error 500) + vertx3: missing_feature (login endpoints not implemented) + vertx4: missing_feature (login endpoints not implemented) + Test_V3_Login_Events_Blocking: + '*': v1.45.0 + akka-http: missing_feature (login endpoints not implemented) + jersey-grizzly2: missing_feature (login endpoints not implemented) + play: missing_feature (login endpoints not implemented) + ratpack: missing_feature (login endpoints not implemented) + resteasy-netty3: missing_feature (login endpoints not implemented) + spring-boot-3-native: flaky (APMAPI-979) + spring-boot-openliberty: missing_feature (weblog returns error 500) + spring-boot-payara: bug (APPSEC-54985) + vertx3: missing_feature (login endpoints not implemented) + vertx4: missing_feature (login endpoints not implemented) + Test_V3_Login_Events_RC: + '*': v1.45.0 + akka-http: missing_feature (login endpoints not implemented) + jersey-grizzly2: missing_feature (login endpoints not implemented) + play: missing_feature (login endpoints not implemented) + ratpack: missing_feature (login endpoints not implemented) + resteasy-netty3: missing_feature (login endpoints not implemented) + spring-boot-3-native: flaky (APMAPI-979) + spring-boot-openliberty: missing_feature (weblog returns error 500) + vertx3: missing_feature (login endpoints not implemented) + vertx4: missing_feature (login endpoints not implemented) + test_automated_user_and_session_tracking.py: + Test_Automated_Session_Blocking: missing_feature + Test_Automated_User_Blocking: + '*': v1.45.0 + akka-http: missing_feature (login endpoints not implemented) + jersey-grizzly2: missing_feature (login endpoints not implemented) + play: missing_feature (login endpoints not implemented) + ratpack: missing_feature (login endpoints not implemented) + resteasy-netty3: missing_feature (login endpoints not implemented) + spring-boot-3-native: flaky (APMAPI-979) + spring-boot-openliberty: missing_feature (weblog returns error 500) + spring-boot-payara: bug (APPSEC-54985) + vertx3: missing_feature (login endpoints not implemented) + vertx4: missing_feature (login endpoints not implemented) + Test_Automated_User_Tracking: + '*': v1.45.0 + akka-http: missing_feature (login endpoints not implemented) + jersey-grizzly2: missing_feature (login endpoints not implemented) + play: missing_feature (login endpoints not implemented) + ratpack: missing_feature (login endpoints not implemented) + resteasy-netty3: missing_feature (login endpoints not implemented) + spring-boot-3-native: flaky (APMAPI-979) + spring-boot-openliberty: missing_feature (weblog returns error 500) + vertx3: missing_feature (login endpoints not implemented) + vertx4: missing_feature (login endpoints not implemented) test_blocking_addresses.py: - Test_BlockingAddresses: + Test_BlockingGraphqlResolvers: missing_feature + Test_Blocking_client_ip: '*': v0.111.0 akka-http: v1.22.0 jersey-grizzly2: v1.7.0 @@ -596,13 +1115,22 @@ tests/: spring-boot-openliberty: v0.115.0 vertx3: v1.7.0 vertx4: v1.7.0 - Test_BlockingGraphqlResolvers: missing_feature Test_Blocking_request_body: '*': v1.15.0 akka-http: v1.22.0 play: v1.22.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) - spring-boot-payara: bug (blocking not working) + spring-boot-payara: bug (APPSEC-54985) + Test_Blocking_request_body_multipart: + '*': v1.15.0 + akka-http: v1.22.0 + jersey-grizzly2: missing_feature + play: v1.22.0 + ratpack: missing_feature + resteasy-netty3: missing_feature + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-openliberty: bug (APPSEC-54985) + spring-boot-payara: bug (APPSEC-54985) Test_Blocking_request_cookies: '*': missing_feature akka-http: v1.22.0 @@ -614,7 +1142,10 @@ tests/: spring-boot-3-native: missing_feature (GraalVM. Tracing support only) spring-boot-jetty: v0.111.0 spring-boot-openliberty: v0.115.0 # Supported since 0.111.0 but bugged in <0.115.0. + spring-boot-payara: v1.35.0 # earlier, but real version not known spring-boot-undertow: v0.111.0 + spring-boot-wildfly: v1.35.0 # earlier, but real version not known + uds-spring-boot: v0.110.0 vertx3: v1.7.0 vertx4: v1.7.0 Test_Blocking_request_headers: @@ -628,7 +1159,10 @@ tests/: spring-boot-3-native: missing_feature (GraalVM. Tracing support only) spring-boot-jetty: v0.111.0 spring-boot-openliberty: v0.115.0 # Supported since 0.111.0 but bugged in <0.115.0. + spring-boot-payara: v1.35.0 # earlier, but real version not known spring-boot-undertow: v0.111.0 + spring-boot-wildfly: v1.35.0 # earlier, but real version not known + uds-spring-boot: v0.110.0 vertx3: v1.7.0 vertx4: v1.7.0 Test_Blocking_request_method: @@ -642,7 +1176,10 @@ tests/: spring-boot-3-native: missing_feature (GraalVM. Tracing support only) spring-boot-jetty: v0.111.0 spring-boot-openliberty: v0.115.0 # Supported since 0.111.0 but bugged in <0.115.0. + spring-boot-payara: v1.35.0 # earlier, but real version not known spring-boot-undertow: v0.111.0 + spring-boot-wildfly: v1.35.0 # earlier, but real version not known + uds-spring-boot: v0.110.0 vertx3: v1.7.0 vertx4: v1.7.0 Test_Blocking_request_path_params: @@ -662,7 +1199,10 @@ tests/: spring-boot-3-native: missing_feature (GraalVM. Tracing support only) spring-boot-jetty: v0.111.0 spring-boot-openliberty: v0.115.0 # Supported since 0.111.0 but bugged in <0.115.0. + spring-boot-payara: v1.35.0 # earlier, but real version not known spring-boot-undertow: v0.111.0 + spring-boot-wildfly: v1.35.0 # earlier, but real version not known + uds-spring-boot: v0.110.0 vertx3: v1.7.0 vertx4: v1.7.0 Test_Blocking_request_uri: @@ -676,7 +1216,10 @@ tests/: spring-boot-3-native: missing_feature (GraalVM. Tracing support only) spring-boot-jetty: v0.111.0 spring-boot-openliberty: v0.115.0 # Supported since 0.111.0 but bugged in <0.115.0. + spring-boot-payara: v1.35.0 # earlier, but real version not known spring-boot-undertow: v0.111.0 + spring-boot-wildfly: v1.35.0 # earlier, but real version not known + uds-spring-boot: v0.110.0 vertx3: v1.7.0 vertx4: v1.7.0 Test_Blocking_response_headers: @@ -689,7 +1232,24 @@ tests/: akka-http: v1.22.0 play: v1.22.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) - Test_Suspicious_Request_Blocking: missing_feature + spring-boot-openliberty: v1.20.0 + Test_Blocking_user_id: + '*': v0.111.0 + akka-http: v1.22.0 + jersey-grizzly2: v1.7.0 + play: v1.22.0 + ratpack: v1.6.0 + resteasy-netty3: v1.7.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-openliberty: v0.115.0 + spring-boot-payara: bug (APPSEC-54966) + vertx3: v1.7.0 + vertx4: v1.7.0 + Test_Suspicious_Request_Blocking: + '*': v1.6.0 + akka-http: bug (APPSEC-54985) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + spring-boot-payara: bug (APPSEC-54985) test_client_ip.py: Test_StandardTagsClientIp: v0.114.0 test_conf.py: @@ -697,14 +1257,6 @@ tests/: '*': v0.100.0 akka-http: v1.22.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) - Test_RuleSet_1_3_1: - '*': v0.99.0 - akka-http: v1.22.0 - spring-boot-3-native: missing_feature (GraalVM. Tracing support only) - Test_StaticRuleSet: - '*': v0.87.0 - akka-http: v1.22.0 - spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_customconf.py: Test_ConfRuleSet: '*': v0.93.0 @@ -739,6 +1291,38 @@ tests/: '*': v1.8.0 play: v1.22.0 spring-boot-3-native: irrelevant (GraalVM. Tracing support only) + test_fingerprinting.py: + Test_Fingerprinting_Endpoint: + '*': v1.39.0 + spring-boot-3-native: irrelevant (GraalVM. Tracing support only) + Test_Fingerprinting_Endpoint_Capability: + '*': v1.39.0 + spring-boot-3-native: irrelevant (GraalVM. Tracing support only) + Test_Fingerprinting_Header_And_Network: + '*': v1.39.0 + spring-boot-3-native: irrelevant (GraalVM. Tracing support only) + Test_Fingerprinting_Header_Capability: + '*': v1.39.0 + spring-boot-3-native: irrelevant (GraalVM. Tracing support only) + Test_Fingerprinting_Network_Capability: + '*': v1.39.0 + spring-boot-3-native: irrelevant (GraalVM. Tracing support only) + Test_Fingerprinting_Session: + '*': v1.40.0 + akka-http: missing_feature (endpoint not implemented) + jersey-grizzly2: missing_feature (endpoint not implemented) + play: missing_feature (endpoint not implemented) + ratpack: missing_feature (endpoint not implemented) + resteasy-netty3: missing_feature (endpoint not implemented) + spring-boot-3-native: irrelevant (GraalVM. Tracing support only) + spring-boot-jetty: missing_feature (missing addresses) + spring-boot-undertow: missing_feature (missing addresses) + spring-boot-wildfly: missing_feature (missing addresses) + vertx3: missing_feature (endpoint not implemented) + vertx4: missing_feature (endpoint not implemented) + Test_Fingerprinting_Session_Capability: + '*': v1.40.0 + spring-boot-3-native: irrelevant (GraalVM. Tracing support only) test_identify.py: Test_Basic: missing_feature test_ip_blocking_full_denylist.py: @@ -756,11 +1340,21 @@ tests/: akka-http: v1.22.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) Test_StandardizationBlockMode: missing_feature + test_metastruct.py: missing_feature test_rate_limiter.py: Test_Main: akka-http: v1.22.0 play: v1.22.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + test_remote_config_rule_changes.py: + Test_BlockingActionChangesWithRemoteConfig: + '*': v1.42.0 + play: bug (APPSEC-55789) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_UpdateRuleFileWithRemoteConfig: + '*': v1.42.0 + play: bug (APPSEC-55791) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_reports.py: Test_AttackTimestamp: akka-http: v1.22.0 @@ -768,11 +1362,6 @@ tests/: Test_ExtraTagsFromRule: '*': v1.22.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) - Test_HttpClientIP: - '*': v0.98.1 - akka-http: v1.22.0 - play: v1.22.0 - spring-boot-3-native: missing_feature (GraalVM. Tracing support only) Test_Info: '*': v0.87.0 akka-http: v1.22.0 @@ -789,23 +1378,21 @@ tests/: spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_request_blocking.py: Test_AppSecRequestBlocking: - '*': missing_feature + '*': v1.9.0 akka-http: v1.22.0 - jersey-grizzly2: v1.9.0 play: v1.22.0 - ratpack: v1.9.0 - resteasy-netty3: v1.9.0 - spring-boot: v1.9.0 - spring-boot-jetty: v1.9.0 - spring-boot-openliberty: v1.9.0 - spring-boot-undertow: v1.9.0 - vertx3: v1.9.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_runtime_activation.py: Test_RuntimeActivation: '*': v0.115.0 akka-http: v1.22.0 play: v1.22.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) + Test_RuntimeDeactivation: + '*': v0.115.0 + akka-http: v1.22.0 + play: v1.22.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_shell_execution.py: Test_ShellExecution: '*': v1.2.0 @@ -817,6 +1404,11 @@ tests/: spring-boot-3-native: missing_feature (disabled on GraalVM) vertx3: missing_feature (endpoint not implemented) vertx4: missing_feature (endpoint not implemented) + test_suspicious_attacker_blocking.py: + Test_Suspicious_Attacker_Blocking: + '*': v1.39.0 + play: bug (APPSEC-54986) + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) test_traces.py: Test_AppSecEventSpanTags: '*': v0.104.0 @@ -827,14 +1419,17 @@ tests/: '*': v0.113.0 akka-http: v1.22.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) - Test_CollectDefaultRequestHeader: missing_feature + Test_CollectDefaultRequestHeader: + '*': v1.35.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) Test_CollectRespondHeaders: '*': v0.102.0 akka-http: v1.22.0 play: v1.22.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) - Test_DistributedTraceInfo: missing_feature (test not implemented) - Test_ExternalWafRequestsIdentification: missing_feature + Test_ExternalWafRequestsIdentification: + '*': v1.35.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) Test_RetainTraces: '*': v0.92.0 akka-http: v1.22.0 @@ -852,33 +1447,59 @@ tests/: test_versions.py: Test_Events: v0.90.0 debugger/: - test_debugger.py: - Test_Debugger_Line_Probe_Snaphots: - '*': missing_feature - spring-boot: v0.1 # real version not known - uds-spring-boot: v0.1 # real version not known - Test_Debugger_Method_Probe_Snaphots: - '*': missing_feature - spring-boot: v0.1 # real version not known - uds-spring-boot: v0.1 # real version not known - Test_Debugger_Mix_Log_Probe: + test_debugger_exception_replay.py: + Test_Debugger_Exception_Replay: '*': missing_feature - spring-boot: v0.1 # real version not known - uds-spring-boot: v0.1 # real version not known - Test_Debugger_Probe_Statuses: - '*': missing_feature - spring-boot: v0.1 # real version not known - uds-spring-boot: v0.1 # real version not known + spring-boot: v1.33.0 + uds-spring-boot: v1.33.0 test_debugger_expression_language.py: Test_Debugger_Expression_Language: '*': missing_feature - spring-boot: v0.1 # real version not known - uds-spring-boot: v0.1 # real version not known + spring-boot: v1.33.0 + spring-boot-jetty: v1.38.0 + spring-boot-openliberty: v1.38.0 + spring-boot-payara: v1.38.0 + spring-boot-undertow: v1.38.0 + spring-boot-wildfly: v1.38.0 + uds-spring-boot: v1.33.0 test_debugger_pii.py: - Test_Debugger_PII_Redaction: + Test_Debugger_PII_Redaction: '*': missing_feature spring-boot: v1.33.0 + spring-boot-jetty: v1.38.0 + spring-boot-openliberty: v1.38.0 + spring-boot-payara: v1.38.0 + spring-boot-undertow: v1.38.0 + spring-boot-wildfly: v1.38.0 + uds-spring-boot: v1.33.0 + test_debugger_probe_snapshot.py: + Test_Debugger_Probe_Snaphots: + '*': missing_feature + spring-boot: v1.33.0 + spring-boot-jetty: v1.38.0 + spring-boot-openliberty: v1.38.0 + spring-boot-payara: v1.38.0 + spring-boot-undertow: v1.38.0 + spring-boot-wildfly: v1.38.0 uds-spring-boot: v1.33.0 + '*': missing_feature + spring-boot: v1.38.0 + spring-boot-jetty: v1.38.0 + spring-boot-openliberty: v1.38.0 + spring-boot-payara: v1.38.0 + spring-boot-undertow: v1.38.0 + spring-boot-wildfly: v1.38.0 + uds-spring-boot: v1.38.0 + test_debugger_probe_status.py: + Test_Debugger_Probe_Statuses: + '*': missing_feature + spring-boot: v1.38.0 + spring-boot-jetty: v1.38.0 + spring-boot-openliberty: v1.38.0 + spring-boot-payara: v1.38.0 + spring-boot-undertow: v1.38.0 + spring-boot-wildfly: v1.38.0 + uds-spring-boot: v1.38.0 integrations/: crossed_integrations/: test_kafka.py: @@ -896,7 +1517,7 @@ tests/: test_sns_to_sqs.py: Test_SNS_Propagation: "*": irrelevant - spring-boot: v0.1 # real version not known + spring-boot: v1.38.0 test_sqs.py: Test_SQS_PROPAGATION_VIA_AWS_XRAY_HEADERS: "*": irrelevant @@ -905,7 +1526,7 @@ tests/: "*": irrelevant spring-boot: v0.1 # real version not known test_cassandra.py: - Test_Cassandra: bug (Endpoint is probably improperly implemented on weblog) + Test_Cassandra: bug (APMAPI-729) test_db_integrations_sql.py: Test_MsSql: '*': missing_feature @@ -945,28 +1566,64 @@ tests/: spring-boot: v1.13.0 Test_DsmSNS: "*": irrelevant - spring-boot: v0.1 # real version not known + spring-boot: v1.38.0 Test_DsmSQS: "*": irrelevant spring-boot: v0.1 # real version not known + Test_Dsm_Manual_Checkpoint_Inter_Process: + "*": irrelevant + spring-boot: bug (AIDM-325) + Test_Dsm_Manual_Checkpoint_Intra_Process: + "*": irrelevant + spring-boot: bug (AIDM-325) + test_inferred_proxy.py: + Test_AWS_API_Gateway_Inferred_Span_Creation: missing_feature test_mongo.py: - Test_Mongo: bug (Endpoint is probably improperly implemented on weblog) + Test_Mongo: bug (APMAPI-729) + test_otel_drop_in.py: + Test_Otel_Drop_In: + '*': missing_feature + spring-boot: v1.39.0 test_sql.py: - Test_Sql: bug (Endpoint is probably improperly implemented on weblog) + Test_Sql: bug (APMAPI-729) + k8s_lib_injection/: + test_k8s_manual_inject.py: + TestAdmisionControllerProfiling: v1.39.0 parametric/: + test_config_consistency.py: + Test_Config_Dogstatsd: missing_feature (default hostname is inconsistent) + Test_Config_RateLimit: v1.41.1 + Test_Config_Tags: missing_feature + Test_Config_TraceAgentURL: v1.41.1 + Test_Config_TraceEnabled: v1.39.0 + Test_Config_TraceLogDirectory: missing_feature + Test_Config_UnifiedServiceTagging: v1.41.1 + test_crashtracking.py: + Test_Crashtracking: v1.38.0 test_dynamic_configuration.py: - TestDynamicConfigHeaderTags: missing_feature TestDynamicConfigSamplingRules: v1.34.0 - TestDynamicConfigTracingEnabled: missing_feature + TestDynamicConfigTracingEnabled: v1.32.0 TestDynamicConfigV1: v1.17.0 TestDynamicConfigV1_ServiceTargets: v1.31.0 TestDynamicConfigV2: v1.31.0 + test_headers_baggage.py: + Test_Headers_Baggage: missing_feature test_otel_api_interoperability.py: missing_feature test_otel_env_vars.py: - Test_Otel_Env_Vars: missing_feature - test_otel_sdk_interoperability.py: missing_feature + Test_Otel_Env_Vars: v1.35.2 + test_otel_span_with_baggage.py: + Test_Otel_Span_With_Baggage: missing_feature + test_parametric_endpoints.py: + Test_Parametric_DDSpan_Add_Link: incomplete_test_app (add_link endpoint is not implemented) + Test_Parametric_DDTrace_Baggage: incomplete_test_app (baggage endpoints are not implemented) + Test_Parametric_DDTrace_Crash: bug (APMAPI-778) # The crash endpoint does not kill the application + Test_Parametric_DDTrace_Current_Span: bug (APMAPI-778) # Fails to retreive the current span after a span has finished + Test_Parametric_Otel_Baggage: missing_feature (otel baggage is not supported) + Test_Parametric_Otel_Current_Span: bug (APMAPI-778) # Current span endpoint does not return DataDog spans created by the otel api + test_span_events.py: missing_feature test_span_links.py: missing_feature test_telemetry.py: + Test_Consistent_Configs: missing_feature Test_Defaults: v1.31.0 Test_Environment: v1.31.0 Test_TelemetryInstallSignature: v1.27.0 @@ -978,14 +1635,16 @@ tests/: Test_Trace_Sampling_Resource: v1.25.0 Test_Trace_Sampling_Tags: v1.26.0 Test_Trace_Sampling_Tags_Feb2024_Revision: v1.30.0 - Test_Trace_Sampling_With_W3C: missing_feature + Test_Trace_Sampling_With_W3C: v1.26.0 test_tracer.py: Test_TracerSCITagging: v1.12.0 test_tracer_flare.py: TestTracerFlareV1: v1.25.0 remote_config/: test_remote_configuration.py: - Test_RemoteConfigurationExtraServices: missing_feature + Test_RemoteConfigurationExtraServices: + '*': v1.31.0 + spring-boot-3-native: missing_feature (GraalVM. Tracing support only) Test_RemoteConfigurationUpdateSequenceASMDD: '*': v1.4.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) @@ -997,23 +1656,74 @@ tests/: Test_RemoteConfigurationUpdateSequenceLiveDebugging: '*': v1.4.0 spring-boot-3-native: missing_feature (GraalVM. Tracing support only) - Test_RemoteConfigurationUpdateSequenceLiveDebuggingNoCache: irrelevant (cache is implemented) + serverless/: + span_pointers/: + aws/: + test_s3_span_pointers.py: + Test_CopyObject: missing_feature + Test_MultipartUpload: missing_feature + Test_PutObject: missing_feature + stats/: + test_miscs.py: + Test_Miscs: missing_feature + test_stats.py: + Test_Client_Stats: missing_feature test_the_test/: test_json_report.py: Test_Mock: v0.0.99 Test_NotReleased: missing_feature + test_config_consistency.py: + Test_Config_ClientIPHeaderEnabled_False: v1.43.0 + Test_Config_ClientIPHeader_Configured: missing_feature + Test_Config_ClientIPHeader_Precedence: missing_feature (does not support x-forwarded header) + Test_Config_ClientTagQueryString_Configured: + '*': v1.43.0 + 'vertx3': irrelevant (endpoint not implemented) + 'vertx4': irrelevant (endpoint not implemented) + Test_Config_ClientTagQueryString_Empty: + '*': v1.43.0 + 'vertx3': irrelevant (endpoint not implemented) + 'vertx4': irrelevant (endpoint not implemented) + Test_Config_HttpClientErrorStatuses_Default: + '*': irrelevant (500 error) + spring-boot: v1.41.1 + Test_Config_HttpClientErrorStatuses_FeatureFlagCustom: + '*': irrelevant (500 error) + spring-boot: v1.41.1 + Test_Config_HttpServerErrorStatuses_Default: + '*': v1.41.1 + spring-boot-openliberty: irrelevant + Test_Config_HttpServerErrorStatuses_FeatureFlagCustom: + '*': irrelevant (500 error) + spring-boot: v1.41.1 + Test_Config_IntegrationEnabled_False: + '*': irrelevant (kafka endpoints are not implemented) + spring-boot: v1.42.0 + Test_Config_IntegrationEnabled_True: + '*': irrelevant (kafka endpoints are not implemented) + spring-boot: v1.42.0 + Test_Config_ObfuscationQueryStringRegexp_Configured: v1.39.0 + Test_Config_ObfuscationQueryStringRegexp_Empty: v1.39.0 + Test_Config_UnifiedServiceTagging_CustomService: v1.39.0 + Test_Config_UnifiedServiceTagging_Default: v1.39.0 test_data_integrity.py: Test_LibraryHeaders: v1.29.0 test_distributed.py: Test_DistributedHttp: missing_feature + Test_Span_Links_Flags_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) + Test_Span_Links_From_Conflicting_Contexts: v1.43.0 + Test_Span_Links_From_Conflicting_Contexts_Datadog_Precedence: v1.43.0 + Test_Span_Links_Omit_Tracestate_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) test_identify.py: Test_Basic: missing_feature Test_Propagate: missing_feature Test_Propagate_Legacy: missing_feature + test_ipv6.py: missing_feature (APMAPI-869) test_library_conf.py: Test_HeaderTags: missing_feature Test_HeaderTags_Colon_Leading: v0.102.0 Test_HeaderTags_Colon_Trailing: v0.102.0 + Test_HeaderTags_DynamicConfig: missing_feature Test_HeaderTags_Long: v0.102.0 Test_HeaderTags_Short: v0.102.0 Test_HeaderTags_Whitespace_Header: v0.102.0 @@ -1023,7 +1733,7 @@ tests/: test_profiling.py: Test_Profile: akka-http: v1.22.0 - spring-boot-3-native: missing_feature (Tracing-only) + spring-boot-3-native: v1.39.0 vertx3: missing_feature (Endpoint not implemented) vertx4: missing_feature (Endpoint not implemented) test_sampling_rates.py: @@ -1041,6 +1751,7 @@ tests/: Test_Meta: play: irrelevant (top span is akka-http-server) Test_MetricsStandardTags: v1.3.0 + test_span_events.py: incomplete_test_app (Weblog `/add_event` not implemented) test_standard_tags.py: Test_StandardTagsClientIp: '*': v0.114.0 diff --git a/manifests/k8s_cluster_agent.yml b/manifests/k8s_cluster_agent.yml new file mode 100644 index 00000000000..4153381cff8 --- /dev/null +++ b/manifests/k8s_cluster_agent.yml @@ -0,0 +1,8 @@ +tests/: + k8s_lib_injection/: + test_k8s_lib_injection_profiling.py: + TestK8sLibInjectioProfilingClusterEnabled: v7.57.0 + TestK8sLibInjectioProfilingClusterOverride: v7.57.0 + TestK8sLibInjectioProfilingDisabledByDefault: v7.57.0 + test_k8s_manual_inject.py: + TestAdmisionControllerProfiling: v7.57.0 \ No newline at end of file diff --git a/manifests/nodejs.yml b/manifests/nodejs.yml index f22f6766cb9..d12e5a3e158 100644 --- a/manifests/nodejs.yml +++ b/manifests/nodejs.yml @@ -33,6 +33,15 @@ refs: - &ref_5_16_0 '>=5.16.0 || ^4.40.0' - &ref_5_17_0 '>=5.17.0 || ^4.41.0' - &ref_5_18_0 '>=5.18.0 || ^4.42.0' + - &ref_5_20_0 '>=5.20.0 || ^4.44.0' + - &ref_5_22_0 '>=5.22.0 || ^4.46.0' + - &ref_5_23_0 '>=5.23.0 || ^4.47.0' + - &ref_5_24_0 '>=5.24.0 || ^4.48.0' + - &ref_5_25_0 '>=5.25.0 || ^4.49.0' + - &ref_5_26_0 '>=5.26.0 || ^4.50.0' + - &ref_5_27_0 '>=5.27.0 || ^4.51.0' + - &ref_5_29_0 '>=5.29.0 || ^4.53.0' # express 5 support + - &ref_5_30_0 '>=5.30.0 || ^4.54.0' tests/: apm_tracing_e2e/: @@ -45,35 +54,57 @@ tests/: test_api_security_rc.py: Test_API_Security_RC_ASM_DD_processors: *ref_5_3_0 Test_API_Security_RC_ASM_DD_scanners: *ref_5_3_0 - Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: missing_feature # waf does not support it yet + Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: irrelevant (waf does not support it yet) test_apisec_sampling.py: - Test_API_Security_sampling: *ref_4_21_0 + Test_API_Security_Sampling_Different_Endpoints: + '*': *ref_5_27_0 + nextjs: missing_feature + Test_API_Security_Sampling_Different_Paths: + '*': *ref_5_27_0 + nextjs: missing_feature + Test_API_Security_Sampling_Different_Status: + '*': *ref_5_27_0 + nextjs: missing_feature + Test_API_Security_Sampling_Rate: irrelevant (new api security sampling algorithm implemented) + Test_API_Security_Sampling_With_Delay: + '*': *ref_5_27_0 + nextjs: missing_feature test_schemas.py: Test_Scanners: *ref_4_21_0 Test_Schema_Request_Cookies: *ref_4_21_0 Test_Schema_Request_FormUrlEncoded_Body: - express4: *ref_4_21_0 - express4-typescript: *ref_4_21_0 + '*': *ref_4_21_0 nextjs: *ref_5_3_0 Test_Schema_Request_Headers: *ref_4_21_0 Test_Schema_Request_Json_Body: *ref_4_21_0 - Test_Schema_Request_Path_Parameters: missing_feature (path_params not supported yet) + Test_Schema_Request_Path_Parameters: + '*': *ref_4_21_0 + express5: *ref_5_29_0 + nextjs: missing_feature Test_Schema_Request_Query_Parameters: *ref_4_21_0 Test_Schema_Response_Body: '*': *ref_5_3_0 + express5: *ref_5_29_0 nextjs: missing_feature Test_Schema_Response_Body_env_var: missing_feature Test_Schema_Response_Headers: *ref_4_21_0 iast/: sink/: + test_code_injection.py: + TestCodeInjection: + '*': *ref_5_20_0 + nextjs: missing_feature + TestCodeInjection_StackTrace: missing_feature test_command_injection.py: TestCommandInjection: '*': *ref_3_11_0 nextjs: missing_feature + TestCommandInjection_StackTrace: missing_feature test_hardcoded_passwords.py: Test_HardcodedPasswords: '*': *ref_5_13_0 nextjs: missing_feature + Test_HardcodedPasswords_StackTrace: missing_feature test_hardcoded_secrets.py: Test_HardcodedSecrets: '*': *ref_4_18_0 @@ -81,81 +112,139 @@ tests/: Test_HardcodedSecretsExtended: '*': *ref_5_11_0 nextjs: missing_feature + Test_HardcodedSecrets_StackTrace: missing_feature test_header_injection.py: TestHeaderInjection: '*': *ref_4_21_0 nextjs: missing_feature + TestHeaderInjectionExclusionAccessControlAllow: + '*': *ref_5_26_0 + express5: *ref_5_29_0 # test uses querystring + nextjs: missing_feature + TestHeaderInjectionExclusionContentEncoding: + '*': *ref_5_26_0 + express5: *ref_5_29_0 # test uses querystring + nextjs: missing_feature + TestHeaderInjectionExclusionPragma: + '*': *ref_5_26_0 + express5: *ref_5_29_0 # test uses querystring + nextjs: missing_feature + TestHeaderInjectionExclusionTransferEncoding: + '*': *ref_5_26_0 + express5: *ref_5_29_0 # test uses querystring + nextjs: missing_feature + TestHeaderInjection_StackTrace: missing_feature test_hsts_missing_header.py: Test_HstsMissingHeader: '*': *ref_4_8_0 nextjs: missing_feature + Test_HstsMissingHeader_StackTrace: missing_feature test_insecure_auth_protocol.py: Test_InsecureAuthProtocol: missing_feature + Test_InsecureAuthProtocol_StackTrace: missing_feature test_insecure_cookie.py: TestInsecureCookie: '*': *ref_4_1_0 nextjs: missing_feature + TestInsecureCookieNameFilter: + '*': *ref_5_24_0 + nextjs: missing_feature + TestInsecureCookie_StackTrace: missing_feature test_ldap_injection.py: TestLDAPInjection: '*': *ref_4_1_0 nextjs: missing_feature + TestLDAPInjection_StackTrace: missing_feature test_no_httponly_cookie.py: TestNoHttponlyCookie: '*': *ref_4_3_0 nextjs: missing_feature + TestNoHttponlyCookieNameFilter: + '*': *ref_5_24_0 + nextjs: missing_feature + TestNoHttponlyCookie_StackTrace: missing_feature test_no_samesite_cookie.py: TestNoSamesiteCookie: '*': *ref_4_3_0 nextjs: missing_feature + TestNoSamesiteCookieNameFilter: + '*': *ref_5_24_0 + nextjs: missing_feature + TestNoSamesiteCookie_StackTrace: missing_feature test_nosql_mongodb_injection.py: TestNoSqlMongodbInjection: '*': *ref_4_17_0 nextjs: missing_feature + TestNoSqlMongodbInjection_StackTrace: missing_feature test_path_traversal.py: TestPathTraversal: '*': *ref_3_19_0 nextjs: missing_feature + TestPathTraversal_StackTrace: missing_feature test_reflection_injection.py: TestReflectionInjection: missing_feature + TestReflectionInjection_StackTrace: missing_feature test_sql_injection.py: TestSqlInjection: '*': *ref_3_11_0 nextjs: missing_feature + TestSqlInjection_StackTrace: missing_feature test_ssrf.py: TestSSRF: '*': *ref_4_1_0 nextjs: missing_feature + TestSSRF_StackTrace: missing_feature + test_template_injection.py: + TestTemplateInjection: + '*': *ref_5_26_0 + nextjs: missing_feature test_trust_boundary_violation.py: Test_TrustBoundaryViolation: missing_feature + Test_TrustBoundaryViolation_StackTrace: missing_feature + test_untrusted_deserialization.py: + TestUntrustedDeserialization: missing_feature + TestUntrustedDeserialization_StackTrace: missing_feature test_unvalidated_redirect.py: TestUnvalidatedHeader: '*': *ref_4_3_0 nextjs: missing_feature + TestUnvalidatedHeader_StackTrace: missing_feature TestUnvalidatedRedirect: '*': *ref_4_3_0 nextjs: missing_feature + TestUnvalidatedRedirect_StackTrace: missing_feature test_unvalidated_redirect_forward.py: TestUnvalidatedForward: missing_feature + TestUnvalidatedForward_StackTrace: missing_feature test_weak_cipher.py: TestWeakCipher: '*': *ref_3_6_0 nextjs: missing_feature + TestWeakCipher_StackTrace: missing_feature test_weak_hash.py: + TestDeduplication: + '*': *ref_3_11_0 + nextjs: missing_feature TestWeakHash: '*': *ref_3_11_0 nextjs: missing_feature + TestWeakHash_StackTrace: missing_feature test_weak_randomness.py: TestWeakRandomness: '*': *ref_5_1_0 nextjs: missing_feature + TestWeakRandomness_StackTrace: missing_feature test_xcontent_sniffing.py: Test_XContentSniffing: '*': *ref_4_8_0 nextjs: missing_feature + Test_XContentSniffing_StackTrace: missing_feature test_xpath_injection.py: TestXPathInjection: missing_feature + TestXPathInjection_StackTrace: missing_feature test_xss.py: TestXSS: missing_feature + TestXSS_StackTrace: missing_feature source/: test_body.py: TestRequestBody: @@ -170,6 +259,7 @@ tests/: test_graphql_resolver.py: TestGraphqlResolverArgument: '*': *ref_5_4_0 + express5: missing_feature # graphql not yet compatible with express5 nextjs: irrelevant # nextjs is not related with graphql test_header_name.py: TestHeaderName: missing_feature @@ -192,19 +282,138 @@ tests/: test_parameter_value.py: TestParameterValue: '*': *ref_3_19_0 + express5: *ref_5_29_0 nextjs: missing_feature test_path.py: TestPath: missing_feature + test_path_parameter.py: + TestPathParameter: + '*': *ref_4_4_0 + express5: *ref_5_29_0 + nextjs: missing_feature + test_sql_row.py: + TestSqlRow: + '*': *ref_5_29_0 + nextjs: missing_feature test_uri.py: TestURI: missing_feature rasp/: - test_lfi.py: missing_feature - test_span_tags.py: - Test_Mandatory_SpanTags: *ref_5_18_0 - Test_Optional_SpanTags: *ref_5_18_0 - test_sqli.py: missing_feature - test_ssrf.py: missing_feature - test_stack_traces.py: missing_feature + test_cmdi.py: + Test_Cmdi_BodyJson: + '*': *ref_5_30_0 + nextjs: missing_feature + Test_Cmdi_BodyUrlEncoded: + '*': *ref_5_30_0 + nextjs: missing_feature + Test_Cmdi_BodyXml: missing_feature + Test_Cmdi_Capability: *ref_5_30_0 + Test_Cmdi_Mandatory_SpanTags: *ref_5_30_0 + Test_Cmdi_Optional_SpanTags: *ref_5_30_0 + Test_Cmdi_Rules_Version: *ref_5_30_0 + Test_Cmdi_StackTrace: + '*': *ref_5_30_0 + nextjs: missing_feature + Test_Cmdi_Telemetry: + '*': *ref_5_30_0 + nextjs: missing_feature + Test_Cmdi_Telemetry_Variant_Tag: + '*': *ref_5_30_0 + nextjs: missing_feature + Test_Cmdi_UrlQuery: + '*': *ref_5_30_0 + nextjs: missing_feature + Test_Cmdi_Waf_Version: *ref_5_30_0 + test_lfi.py: + Test_Lfi_BodyJson: + '*': *ref_5_24_0 + express5: *ref_5_29_0 + nextjs: missing_feature + Test_Lfi_BodyUrlEncoded: + '*': *ref_5_24_0 + express5: *ref_5_29_0 + nextjs: missing_feature + Test_Lfi_BodyXml: missing_feature + Test_Lfi_Capability: *ref_5_24_0 + Test_Lfi_Mandatory_SpanTags: *ref_5_24_0 + Test_Lfi_Optional_SpanTags: *ref_5_24_0 + Test_Lfi_RC_CustomAction: + '*': *ref_5_24_0 + express5: *ref_5_29_0 + nextjs: missing_feature + Test_Lfi_Rules_Version: *ref_5_26_0 + Test_Lfi_StackTrace: *ref_5_24_0 + Test_Lfi_Telemetry: *ref_5_24_0 + Test_Lfi_UrlQuery: + '*': *ref_5_24_0 + express5: *ref_5_29_0 + nextjs: missing_feature + Test_Lfi_Waf_Version: *ref_5_25_0 + test_shi.py: + Test_Shi_BodyJson: + '*': *ref_5_25_0 + express5: *ref_5_29_0 + nextjs: missing_feature + Test_Shi_BodyUrlEncoded: + '*': *ref_5_25_0 + express5: *ref_5_29_0 + nextjs: missing_feature + Test_Shi_BodyXml: missing_feature + Test_Shi_Capability: *ref_5_25_0 + Test_Shi_Mandatory_SpanTags: *ref_5_25_0 + Test_Shi_Optional_SpanTags: *ref_5_25_0 + Test_Shi_Rules_Version: *ref_5_24_0 + Test_Shi_StackTrace: *ref_5_25_0 + Test_Shi_Telemetry: *ref_5_25_0 + Test_Shi_Telemetry_Variant_Tag: *ref_5_30_0 + Test_Shi_UrlQuery: + '*': *ref_5_25_0 + express5: *ref_5_29_0 + nextjs: missing_feature + Test_Shi_Waf_Version: *ref_5_25_0 + test_sqli.py: + Test_Sqli_BodyJson: + '*': *ref_5_23_0 + express5: *ref_5_29_0 + nextjs: missing_feature + Test_Sqli_BodyUrlEncoded: + '*': *ref_5_23_0 + express5: *ref_5_29_0 + nextjs: missing_feature + Test_Sqli_BodyXml: missing_feature + Test_Sqli_Capability: *ref_5_23_0 + Test_Sqli_Mandatory_SpanTags: *ref_5_23_0 + Test_Sqli_Optional_SpanTags: *ref_5_23_0 + Test_Sqli_Rules_Version: *ref_5_25_0 + Test_Sqli_StackTrace: *ref_5_23_0 + Test_Sqli_Telemetry: *ref_5_23_0 + Test_Sqli_UrlQuery: + '*': *ref_5_23_0 + express5: *ref_5_29_0 + nextjs: missing_feature + Test_Sqli_Waf_Version: *ref_5_25_0 + test_ssrf.py: + Test_Ssrf_BodyJson: + '*': *ref_5_20_0 + nextjs: missing_feature + Test_Ssrf_BodyUrlEncoded: + '*': *ref_5_20_0 + nextjs: missing_feature + Test_Ssrf_BodyXml: missing_feature # xml body not supported + Test_Ssrf_Capability: *ref_5_23_0 + Test_Ssrf_Mandatory_SpanTags: *ref_5_18_0 + Test_Ssrf_Optional_SpanTags: *ref_5_18_0 + Test_Ssrf_Rules_Version: *ref_5_25_0 + Test_Ssrf_StackTrace: + '*': *ref_5_20_0 + express5: *ref_5_29_0 # test uses querystring + Test_Ssrf_Telemetry: + '*': *ref_5_22_0 + express5: *ref_5_29_0 # test uses querystring + Test_Ssrf_UrlQuery: + '*': *ref_5_20_0 + express5: *ref_5_29_0 + nextjs: missing_feature + Test_Ssrf_Waf_Version: *ref_5_25_0 waf/: test_addresses.py: Test_BodyJson: @@ -217,18 +426,17 @@ tests/: Test_BodyXml: '*': v2.2.0 nextjs: irrelevant # Body xml is not converted to JSON in nextjs - Test_ClientIP: missing_feature Test_Cookies: v2.0.0 Test_FullGrpc: missing_feature Test_GraphQL: '*': *ref_4_22_0 + express5: missing_feature # graphql not yet compatible with express5 nextjs: irrelevant # nextjs is not related with graphql Test_GrpcServerMethod: missing_feature Test_Headers: v2.0.0 - Test_Lambda: missing_feature - Test_Method: missing_feature Test_PathParams: '*': v2.0.0 + express5: *ref_5_29_0 nextjs: missing_feature Test_ResponseStatus: v2.0.0 Test_UrlQuery: @@ -270,54 +478,77 @@ tests/: Test_XSS: v2.0.0 test_telemetry.py: Test_TelemetryMetrics: *ref_4_17_0 - test_PII.py: - Test_Scrubbing: missing_feature test_alpha.py: Test_Basic: v2.0.0 test_asm_standalone.py: - Test_AppSecStandalone_UpstreamPropagation: missing_feature + Test_AppSecStandalone_UpstreamPropagation: *ref_5_18_0 + Test_IastStandalone_UpstreamPropagation: *ref_5_29_0 + Test_SCAStandalone_Telemetry: *ref_5_18_0 test_automated_login_events.py: - Test_Login_Events: - '*': *ref_4_4_0 - nextjs: missing_feature - Test_Login_Events_Extended: - '*': *ref_4_4_0 - nextjs: missing_feature - Test_V2_Login_Events: missing_feature - Test_V2_Login_Events_Anon: missing_feature - Test_V2_Login_Events_RC: missing_feature + Test_Login_Events: irrelevant + Test_Login_Events_Extended: irrelevant + Test_V2_Login_Events: irrelevant + Test_V2_Login_Events_Anon: irrelevant + Test_V2_Login_Events_RC: irrelevant + Test_V3_Auto_User_Instrum_Mode_Capability: *ref_5_29_0 + Test_V3_Login_Events: + '*': *ref_5_29_0 + nextjs: missing_feature + Test_V3_Login_Events_Anon: + '*': *ref_5_29_0 + nextjs: missing_feature + Test_V3_Login_Events_Blocking: + '*': *ref_5_29_0 + nextjs: missing_feature + Test_V3_Login_Events_RC: + '*': *ref_5_29_0 + nextjs: missing_feature + test_automated_user_and_session_tracking.py: + Test_Automated_Session_Blocking: missing_feature + Test_Automated_User_Blocking: missing_feature + Test_Automated_User_Tracking: missing_feature test_blocking_addresses.py: - Test_BlockingAddresses: *ref_3_19_0 Test_BlockingGraphqlResolvers: '*': *ref_4_22_0 + express5: missing_feature # graphql not yet compatible with express5 nextjs: irrelevant # nextjs is not related with graphql + Test_Blocking_client_ip: *ref_3_19_0 Test_Blocking_request_body: '*': *ref_3_19_0 nextjs: missing_feature + Test_Blocking_request_body_multipart: + '*': *ref_5_25_0 + nextjs: missing_feature Test_Blocking_request_cookies: '*': *ref_4_16_0 nextjs: missing_feature Test_Blocking_request_headers: *ref_3_19_0 Test_Blocking_request_method: *ref_3_19_0 - Test_Blocking_request_path_params: missing_feature + Test_Blocking_request_path_params: + '*': *ref_5_24_0 + express5: *ref_5_29_0 + nextjs: missing_feature Test_Blocking_request_query: '*': *ref_3_19_0 + express5: *ref_5_29_0 nextjs: missing_feature Test_Blocking_request_uri: *ref_3_19_0 Test_Blocking_response_headers: *ref_5_17_0 Test_Blocking_response_status: *ref_5_17_0 + Test_Blocking_user_id: + '*': *ref_3_19_0 + nextjs: missing_feature Test_Suspicious_Request_Blocking: - '*': missing_feature (v3.19.0, but test is not implemented) + '*': *ref_5_24_0 + express5: *ref_5_29_0 # test uses querystring and path params nextjs: missing_feature test_client_ip.py: Test_StandardTagsClientIp: *ref_3_6_0 test_conf.py: Test_ConfigurationVariables: v2.7.0 - Test_RuleSet_1_3_1: v2.5.0 - Test_StaticRuleSet: v2.0.0 test_customconf.py: Test_ConfRuleSet: v2.0.0 - Test_MissingRules: missing_feature + Test_MissingRules: v2.0.0 Test_NoLimitOnWafRules: v2.4.0 test_event_tracking.py: Test_CustomEvent: @@ -329,6 +560,14 @@ tests/: Test_UserLoginSuccessEvent: '*': *ref_3_13_0 nextjs: missing_feature + test_fingerprinting.py: + Test_Fingerprinting_Endpoint: *ref_5_24_0 + Test_Fingerprinting_Endpoint_Capability: *ref_5_24_0 + Test_Fingerprinting_Header_And_Network: *ref_5_24_0 + Test_Fingerprinting_Header_Capability: *ref_5_24_0 + Test_Fingerprinting_Network_Capability: *ref_5_24_0 + Test_Fingerprinting_Session: missing_feature + Test_Fingerprinting_Session_Capability: missing_feature test_identify.py: Test_Basic: v2.4.0 test_ip_blocking_full_denylist.py: @@ -336,28 +575,38 @@ tests/: test_logs.py: Test_Standardization: missing_feature Test_StandardizationBlockMode: missing_feature + test_metastruct.py: + Test_SecurityEvents_Appsec_Metastruct_Disabled: v2.2.0 + Test_SecurityEvents_Appsec_Metastruct_Enabled: missing_feature + Test_SecurityEvents_Iast_Metastruct_Disabled: missing_feature + Test_SecurityEvents_Iast_Metastruct_Enabled: missing_feature test_rate_limiter.py: Test_Main: v2.0.0 + test_remote_config_rule_changes.py: + Test_BlockingActionChangesWithRemoteConfig: *ref_4_1_0 + Test_UpdateRuleFileWithRemoteConfig: *ref_3_19_0 test_reports.py: Test_ExtraTagsFromRule: *ref_4_1_0 - Test_HttpClientIP: v2.0.0 Test_Info: v2.0.0 Test_RequestHeaders: v2.0.0 Test_StatusCode: v2.0.0 test_request_blocking.py: Test_AppSecRequestBlocking: '*': *ref_3_19_0 + express5: *ref_5_29_0 # test uses querystring nextjs: missing_feature (can not block by query param in nextjs yet) test_runtime_activation.py: Test_RuntimeActivation: *ref_3_9_0 + Test_RuntimeDeactivation: *ref_3_9_0 test_shell_execution.py: Test_ShellExecution: *ref_5_3_0 + test_suspicious_attacker_blocking.py: + Test_Suspicious_Attacker_Blocking: missing_feature test_traces.py: Test_AppSecEventSpanTags: v2.0.0 Test_AppSecObfuscator: v2.6.0 - Test_CollectDefaultRequestHeader: missing_feature + Test_CollectDefaultRequestHeader: *ref_5_18_0 Test_CollectRespondHeaders: v2.0.0 - Test_DistributedTraceInfo: missing_feature (test not implemented) Test_ExternalWafRequestsIdentification: *ref_5_7_0 Test_RetainTraces: v2.0.0 test_user_blocking_full_denylist.py: @@ -367,113 +616,179 @@ tests/: test_versions.py: Test_Events: v2.0.0 debugger/: - test_debugger.py: - Test_Debugger_Line_Probe_Snaphots: missing_feature (feature not implented) - Test_Debugger_Method_Probe_Snaphots: missing_feature (feature not implented) - Test_Debugger_Mix_Log_Probe: missing_feature (feature not implented) - Test_Debugger_Probe_Statuses: missing_feature (feature not implented) + test_debugger_exception_replay.py: + Test_Debugger_Exception_Replay: missing_feature (feature not implented) test_debugger_expression_language.py: Test_Debugger_Expression_Language: missing_feature (feature not implented) test_debugger_pii.py: Test_Debugger_PII_Redaction: missing_feature (feature not implented) + test_debugger_probe_snapshot.py: + Test_Debugger_Probe_Snaphots: missing_feature (feature not implented) + test_debugger_probe_status.py: + Test_Debugger_Probe_Statuses: missing_feature (feature not implented) integrations/: crossed_integrations/: test_kafka.py: Test_Kafka: '*': irrelevant express4: v0.1 # real version not known + express5: v0.1 # real version not known test_kinesis.py: Test_Kinesis_PROPAGATION_VIA_MESSAGE_ATTRIBUTES: '*': irrelevant express4: *ref_5_3_0 + express5: *ref_5_3_0 test_rabbitmq.py: Test_RabbitMQ_Trace_Context_Propagation: '*': irrelevant express4: v0.1 # real version not known + express5: v0.1 # real version not known test_sns_to_sqs.py: Test_SNS_Propagation: '*': irrelevant - express4: v0.1 # real version not known + express4: *ref_5_20_0 + express5: *ref_5_20_0 test_sqs.py: Test_SQS_PROPAGATION_VIA_AWS_XRAY_HEADERS: '*': irrelevant express4: v0.1 # real version not known + express5: v0.1 # real version not known Test_SQS_PROPAGATION_VIA_MESSAGE_ATTRIBUTES: '*': irrelevant express4: v0.1 # real version not known + express5: v0.1 # real version not known test_db_integrations_sql.py: Test_MsSql: '*': missing_feature express4: v1.0.0 + express5: v1.0.0 Test_MySql: '*': missing_feature express4: v1.0.0 + express5: v1.0.0 Test_Postgres: '*': missing_feature express4: v1.0.0 + express5: v1.0.0 test_dbm.py: Test_Dbm: missing_feature Test_Dbm_Comment_NodeJS_mysql2: '*': missing_feature (Missing on weblog) express4: *ref_5_13_0 + express5: *ref_5_13_0 + uds-express4: *ref_5_13_0 Test_Dbm_Comment_NodeJS_pg: '*': missing_feature (Missing on weblog) express4: *ref_5_13_0 + express5: *ref_5_13_0 + uds-express4: *ref_5_13_0 test_dsm.py: Test_DsmContext_Extraction_Base64: '*': irrelevant express4: *ref_5_6_0 + express5: *ref_5_6_0 Test_DsmContext_Injection_Base64: '*': irrelevant express4: *ref_5_6_0 + express5: *ref_5_6_0 Test_DsmHttp: missing_feature Test_DsmKafka: - '*': *ref_4_4_0 + '*': *ref_5_25_0 nextjs: missing_feature (missing endpoint) Test_DsmKinesis: '*': irrelevant express4: *ref_5_2_0 + express5: *ref_5_2_0 Test_DsmRabbitmq: '*': irrelevant express4: *ref_5_3_0 + express5: *ref_5_3_0 Test_DsmRabbitmq_FanoutExchange: '*': irrelevant express4: missing_feature + express5: missing_feature Test_DsmRabbitmq_TopicExchange: '*': irrelevant express4: missing_feature + express5: missing_feature Test_DsmSNS: '*': irrelevant - express4: *ref_5_2_0 + express4: *ref_5_20_0 + express5: *ref_5_20_0 Test_DsmSQS: '*': irrelevant express4: *ref_5_2_0 + express5: *ref_5_2_0 + Test_Dsm_Manual_Checkpoint_Inter_Process: + '*': irrelevant + express4: *ref_5_20_0 + express5: *ref_5_20_0 + Test_Dsm_Manual_Checkpoint_Intra_Process: + '*': irrelevant + express4: *ref_5_20_0 + express5: *ref_5_20_0 + test_inferred_proxy.py: + Test_AWS_API_Gateway_Inferred_Span_Creation: + '*': irrelevant + express4: *ref_5_26_0 + express5: *ref_5_26_0 + test_otel_drop_in.py: + Test_Otel_Drop_In: missing_feature + k8s_lib_injection/: + test_k8s_manual_inject.py: + TestAdmisionControllerProfiling: *ref_5_22_0 parametric/: + test_config_consistency.py: + Test_Config_Dogstatsd: *ref_5_29_0 + Test_Config_RateLimit: *ref_5_25_0 + Test_Config_Tags: missing_feature + Test_Config_TraceAgentURL: *ref_5_25_0 + Test_Config_TraceEnabled: *ref_4_3_0 + Test_Config_TraceLogDirectory: missing_feature + Test_Config_UnifiedServiceTagging: *ref_5_25_0 + test_crashtracking.py: + Test_Crashtracking: *ref_5_27_0 test_dynamic_configuration.py: - TestDynamicConfigHeaderTags: missing_feature TestDynamicConfigSamplingRules: *ref_5_16_0 - TestDynamicConfigTracingEnabled: missing_feature + TestDynamicConfigTracingEnabled: *ref_5_4_0 TestDynamicConfigV1: *ref_4_11_0 - TestDynamicConfigV1_ServiceTargets: missing_feature + TestDynamicConfigV1_ServiceTargets: *ref_5_4_0 TestDynamicConfigV2: *ref_4_23_0 + test_headers_baggage.py: + Test_Headers_Baggage: *ref_5_29_0 test_otel_api_interoperability.py: missing_feature test_otel_env_vars.py: Test_Otel_Env_Vars: v5.11.0 #implemented in v5.11.0, v4.35.0, &v3.56.0 - test_otel_sdk_interoperability.py: missing_feature + test_otel_span_with_baggage.py: + Test_Otel_Span_With_Baggage: missing_feature + test_parametric_endpoints.py: + Test_Parametric_DDSpan_Set_Resource: incomplete_test_app (set_resource endpoint is not implemented) + Test_Parametric_DDSpan_Start: bug (APMAPI-778) # The resource name of the child span is overidden by the parent span. + Test_Parametric_DDTrace_Baggage: incomplete_test_app (baggage endpoints are not implemented) + Test_Parametric_DDTrace_Crash: incomplete_test_app (crash endpoint is not implemented) + Test_Parametric_DDTrace_Current_Span: incomplete_test_app (current_span endpoint is not supported) + Test_Parametric_OtelSpan_Set_Name: bug (APMAPI-778) # set_name endpoint should set the resource name on a span (not the operation name) + Test_Parametric_OtelSpan_Start: bug (APMAPI-778) # The expected span.kind tag is not set + Test_Parametric_Otel_Baggage: missing_feature (baggage is not supported) + Test_Parametric_Otel_Current_Span: incomplete_test_app (otel current_span endpoint is not supported) + test_partial_flushing.py: + Test_Partial_Flushing: bug (APMLP-270) + test_span_events.py: missing_feature test_span_links.py: Test_Span_Links: *ref_5_3_0 test_telemetry.py: + Test_Consistent_Configs: *ref_5_25_0 Test_Defaults: *ref_5_6_0 Test_Environment: *ref_5_6_0 Test_TelemetryInstallSignature: *ref_4_23_0 Test_TelemetrySCAEnvVar: *ref_5_13_0 test_trace_sampling.py: - Test_Trace_Sampling_Basic: missing_feature - Test_Trace_Sampling_Globs: missing_feature + Test_Trace_Sampling_Basic: *ref_5_16_0 #actual version unknown + Test_Trace_Sampling_Globs: *ref_5_16_0 #actual version unknown Test_Trace_Sampling_Globs_Feb2024_Revision: missing_feature Test_Trace_Sampling_Resource: missing_feature Test_Trace_Sampling_Tags: missing_feature - Test_Trace_Sampling_Tags_Feb2024_Revision: missing_feature + Test_Trace_Sampling_Tags_Feb2024_Revision: *ref_5_16_0 #actual version unknown Test_Trace_Sampling_With_W3C: missing_feature test_tracer.py: Test_TracerSCITagging: *ref_3_21_0 @@ -486,10 +801,50 @@ tests/: Test_RemoteConfigurationUpdateSequenceASMDDNoCache: irrelevant (cache is implemented) Test_RemoteConfigurationUpdateSequenceFeatures: *ref_3_9_0 Test_RemoteConfigurationUpdateSequenceFeaturesNoCache: irrelevant (cache is implemented) - Test_RemoteConfigurationUpdateSequenceLiveDebugging: missing_feature - Test_RemoteConfigurationUpdateSequenceLiveDebuggingNoCache: irrelevant (cache is implemented) + Test_RemoteConfigurationUpdateSequenceLiveDebugging: *ref_5_16_0 #actual version unknown + serverless/: + span_pointers/: + aws/: + test_s3_span_pointers.py: + Test_CopyObject: missing_feature + Test_MultipartUpload: missing_feature + Test_PutObject: missing_feature + stats/: + test_miscs.py: + Test_Miscs: missing_feature + test_stats.py: + Test_Client_Stats: missing_feature + test_config_consistency.py: + Test_Config_ClientIPHeaderEnabled_False: *ref_3_13_0 + Test_Config_ClientIPHeader_Configured: *ref_3_13_0 + Test_Config_ClientIPHeader_Precedence: *ref_3_19_0 + Test_Config_ClientTagQueryString_Configured: missing_feature (adding query string to http.url is not supported) + Test_Config_ClientTagQueryString_Empty: missing_feature (removes query strings by default) + Test_Config_HttpClientErrorStatuses_Default: missing_feature + Test_Config_HttpClientErrorStatuses_FeatureFlagCustom: missing_feature + Test_Config_HttpServerErrorStatuses_Default: missing_feature + Test_Config_HttpServerErrorStatuses_FeatureFlagCustom: missing_feature + Test_Config_IntegrationEnabled_False: + '*': *ref_5_25_0 + express4-typescript: irrelevant + nextjs: irrelevant # nextjs is not related with kafka + Test_Config_IntegrationEnabled_True: + '*': *ref_5_25_0 + express4-typescript: irrelevant + nextjs: irrelevant # nextjs is not related with kafka + Test_Config_ObfuscationQueryStringRegexp_Configured: *ref_3_0_0 + Test_Config_ObfuscationQueryStringRegexp_Empty: *ref_3_0_0 + Test_Config_UnifiedServiceTagging_CustomService: *ref_5_25_0 + Test_Config_UnifiedServiceTagging_Default: *ref_5_25_0 test_distributed.py: Test_DistributedHttp: missing_feature + Test_Span_Links_Flags_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) + Test_Span_Links_From_Conflicting_Contexts: v5.27.0 + Test_Span_Links_From_Conflicting_Contexts_Datadog_Precedence: v5.27.0 + Test_Span_Links_Omit_Tracestate_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) + Test_Synthetics_APM_Datadog: + '*': *ref_5_25_0 + nextjs: bug (APMAPI-939) # the nextjs weblog application changes the sampling priority from 1.0 to 2.0 test_identify.py: Test_Basic: v2.4.0 Test_Propagate: *ref_3_2_0 @@ -498,14 +853,15 @@ tests/: Test_HeaderTags: *ref_4_11_0 Test_HeaderTags_Colon_Leading: *ref_4_11_0 Test_HeaderTags_Colon_Trailing: *ref_4_11_0 + Test_HeaderTags_DynamicConfig: missing_feature Test_HeaderTags_Long: *ref_4_11_0 Test_HeaderTags_Short: *ref_4_11_0 - Test_HeaderTags_Whitespace_Header: bug (AIT-9109) - Test_HeaderTags_Whitespace_Tag: bug (AIT-9109) + Test_HeaderTags_Whitespace_Header: *ref_5_25_0 + Test_HeaderTags_Whitespace_Tag: *ref_5_25_0 Test_HeaderTags_Whitespace_Val_Long: *ref_4_11_0 Test_HeaderTags_Whitespace_Val_Short: *ref_4_11_0 test_profiling.py: - Test_Profile: bug (Not receiving profiles) + Test_Profile: *ref_5_16_0 #actual version unknown test_scrubbing.py: Test_UrlField: *ref_3_13_1 Test_UrlQuery: @@ -516,6 +872,7 @@ tests/: '*': *ref_3_13_1 nextjs: missing_feature # nextjs makes some internal requests and we have different tag names Test_MetricsStandardTags: *ref_3_13_1 + test_span_events.py: incomplete_test_app (Weblog `/add_event` not implemented) test_standard_tags.py: Test_StandardTagsClientIp: '*': *ref_3_6_0 @@ -530,13 +887,13 @@ tests/: test_telemetry.py: Test_DependencyEnable: missing_feature Test_Log_Generation: missing_feature - Test_MessageBatch: missing_feature + Test_MessageBatch: *ref_4_21_0 Test_Metric_Generation_Disabled: missing_feature Test_Metric_Generation_Enabled: missing_feature - Test_ProductsDisabled: missing_feature + Test_ProductsDisabled: *ref_4_21_0 Test_Telemetry: '*': *ref_3_2_0 nextjs: missing_feature uds-express4: *ref_3_7_0 Test_TelemetrySCAEnvVar: missing_feature - Test_TelemetryV2: missing_feature + Test_TelemetryV2: *ref_4_21_0 diff --git a/utils/parametric/protos/__init__.py b/manifests/parser/__init__.py similarity index 100% rename from utils/parametric/protos/__init__.py rename to manifests/parser/__init__.py diff --git a/manifests/parser/core.py b/manifests/parser/core.py index b50b958bcad..ee2e2575864 100644 --- a/manifests/parser/core.py +++ b/manifests/parser/core.py @@ -11,7 +11,6 @@ def _flatten(base, obj): if base.endswith(".py"): base += "::" for key, value in obj.items(): - if isinstance(value, str): yield f"{base}{key}", value elif isinstance(value, dict): @@ -22,7 +21,6 @@ def _flatten(base, obj): def _load_file(file): - try: with open(file, encoding="utf-8") as f: data = yaml.safe_load(f) @@ -38,8 +36,7 @@ def _load_file(file): @lru_cache def load(base_dir="manifests/"): - """ - Returns a dict of nodeid, value are another dict where the key is the component + """Returns a dict of nodeid, value are another dict where the key is the component and the value the declaration. It is meant to sent directly the value of a nodeid to @released. Data example: @@ -66,6 +63,8 @@ def load(base_dir="manifests/"): "python", "python_otel", "ruby", + "dd_apm_inject", + "k8s_cluster_agent", ): data = _load_file(f"{base_dir}{component}.yml") @@ -78,7 +77,7 @@ def load(base_dir="manifests/"): def assert_key_order(obj: dict, path=""): last_key = "/" - for key in obj: + for key, value in obj.items(): if last_key.endswith("/") and not key.endswith("/"): # transition from folder fo files, nothing to do pass elif not last_key.endswith("/") and key.endswith("/"): # folder must be before files @@ -86,8 +85,8 @@ def assert_key_order(obj: dict, path=""): else: # otherwise, it must be sorted assert last_key < key, f"Order is not respected at {path} ({last_key} < {key})" - if isinstance(obj[key], dict): - assert_key_order(obj[key], f"{path}.{key}") + if isinstance(value, dict): + assert_key_order(value, f"{path}.{key}") last_key = key diff --git a/manifests/parser/schema.json b/manifests/parser/schema.json index 587641fca79..c50feab639b 100644 --- a/manifests/parser/schema.json +++ b/manifests/parser/schema.json @@ -74,7 +74,7 @@ "skipped_declaration": { "type": "string", - "pattern": "^(bug|flaky|irrelevant|missing_feature)( \\(.+\\))?$" + "pattern": "^(bug|flaky|irrelevant|missing_feature|incomplete_test_app)( \\(.+\\))?$" } } } diff --git a/manifests/php.yml b/manifests/php.yml index adc67c93a00..034c7018853 100644 --- a/manifests/php.yml +++ b/manifests/php.yml @@ -9,9 +9,8 @@ tests/: test_api_security_rc.py: Test_API_Security_RC_ASM_DD_processors: missing_feature Test_API_Security_RC_ASM_DD_scanners: missing_feature - Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: missing_feature # waf does not support it yet - test_apisec_sampling.py: - Test_API_Security_sampling: missing_feature + Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: irrelevant (waf does not support it yet) + test_apisec_sampling.py: missing_feature test_schemas.py: Test_Scanners: missing_feature Test_Schema_Request_Cookies: v0.94.0 @@ -25,57 +24,98 @@ tests/: Test_Schema_Response_Headers: v0.94.0 iast/: sink/: + test_code_injection.py: + TestCodeInjection: missing_feature + TestCodeInjection_StackTrace: missing_feature test_command_injection.py: TestCommandInjection: missing_feature + TestCommandInjection_StackTrace: missing_feature test_hardcoded_passwords.py: Test_HardcodedPasswords: missing_feature + Test_HardcodedPasswords_StackTrace: missing_feature test_hardcoded_secrets.py: Test_HardcodedSecrets: missing_feature Test_HardcodedSecretsExtended: missing_feature + Test_HardcodedSecrets_StackTrace: missing_feature test_header_injection.py: TestHeaderInjection: missing_feature + TestHeaderInjectionExclusionAccessControlAllow: missing_feature + TestHeaderInjectionExclusionContentEncoding: missing_feature + TestHeaderInjectionExclusionPragma: missing_feature + TestHeaderInjectionExclusionTransferEncoding: missing_feature + TestHeaderInjection_StackTrace: missing_feature test_hsts_missing_header.py: Test_HstsMissingHeader: missing_feature + Test_HstsMissingHeader_StackTrace: missing_feature test_insecure_auth_protocol.py: Test_InsecureAuthProtocol: missing_feature + Test_InsecureAuthProtocol_StackTrace: missing_feature test_insecure_cookie.py: TestInsecureCookie: missing_feature + TestInsecureCookieNameFilter: missing_feature + TestInsecureCookie_StackTrace: missing_feature test_ldap_injection.py: TestLDAPInjection: missing_feature + TestLDAPInjection_StackTrace: missing_feature test_no_httponly_cookie.py: TestNoHttponlyCookie: missing_feature + TestNoHttponlyCookieNameFilter: missing_feature + TestNoHttponlyCookie_StackTrace: missing_feature test_no_samesite_cookie.py: TestNoSamesiteCookie: missing_feature + TestNoSamesiteCookieNameFilter: missing_feature + TestNoSamesiteCookie_StackTrace: missing_feature test_nosql_mongodb_injection.py: TestNoSqlMongodbInjection: missing_feature + TestNoSqlMongodbInjection_StackTrace: missing_feature test_path_traversal.py: TestPathTraversal: missing_feature + TestPathTraversal_StackTrace: missing_feature test_reflection_injection.py: TestReflectionInjection: missing_feature + TestReflectionInjection_StackTrace: missing_feature test_sql_injection.py: TestSqlInjection: missing_feature + TestSqlInjection_StackTrace: missing_feature test_ssrf.py: TestSSRF: missing_feature + TestSSRF_StackTrace: missing_feature + test_template_injection.py: + TestTemplateInjection: missing_feature test_trust_boundary_violation.py: Test_TrustBoundaryViolation: missing_feature + Test_TrustBoundaryViolation_StackTrace: missing_feature + test_untrusted_deserialization.py: + TestUntrustedDeserialization: missing_feature + TestUntrustedDeserialization_StackTrace: missing_feature test_unvalidated_redirect.py: TestUnvalidatedHeader: missing_feature + TestUnvalidatedHeader_StackTrace: missing_feature TestUnvalidatedRedirect: missing_feature + TestUnvalidatedRedirect_StackTrace: missing_feature test_unvalidated_redirect_forward.py: TestUnvalidatedForward: missing_feature + TestUnvalidatedForward_StackTrace: missing_feature test_weak_cipher.py: TestWeakCipher: missing_feature + TestWeakCipher_StackTrace: missing_feature test_weak_hash.py: + TestDeduplication: missing_feature TestWeakHash: missing_feature + TestWeakHash_StackTrace: missing_feature test_weak_randomness.py: TestWeakRandomness: missing_feature + TestWeakRandomness_StackTrace: missing_feature test_xcontent_sniffing.py: Test_XContentSniffing: missing_feature + Test_XContentSniffing_StackTrace: missing_feature test_xpath_injection.py: TestXPathInjection: missing_feature + TestXPathInjection_StackTrace: missing_feature test_xss.py: TestXSS: '*': missing_feature + TestXSS_StackTrace: missing_feature source/: test_body.py: TestRequestBody: missing_feature @@ -101,28 +141,29 @@ tests/: TestParameterValue: missing_feature test_path.py: TestPath: missing_feature + test_path_parameter.py: + TestPathParameter: missing_feature + test_sql_row.py: + TestSqlRow: missing_feature test_uri.py: TestURI: missing_feature rasp/: + test_cmdi.py: missing_feature test_lfi.py: missing_feature - test_span_tags.py: missing_feature + test_shi.py: missing_feature test_sqli.py: missing_feature test_ssrf.py: missing_feature - test_stack_traces.py: missing_feature waf/: test_addresses.py: Test_BodyJson: v0.98.1 # TODO what is the earliest version? Test_BodyRaw: v0.68.3 Test_BodyUrlEncoded: v0.68.3 - Test_BodyXml: missing_feature - Test_ClientIP: missing_feature + Test_BodyXml: v0.98.0 Test_Cookies: v0.68.3 Test_FullGrpc: missing_feature Test_GraphQL: missing_feature Test_GrpcServerMethod: missing_feature Test_Headers: v0.68.3 - Test_Lambda: missing_feature - Test_Method: missing_feature Test_PathParams: v0.71.0 Test_UrlQuery: v0.68.3 Test_UrlQueryKey: v0.74.0 @@ -158,49 +199,82 @@ tests/: Test_XSS: v0.68.3 test_telemetry.py: Test_TelemetryMetrics: missing_feature - test_PII.py: - Test_Scrubbing: missing_feature test_asm_standalone.py: - Test_AppSecStandalone_UpstreamPropagation: missing_feature + Test_AppSecStandalone_UpstreamPropagation: v1.6.0 + Test_IastStandalone_UpstreamPropagation: missing_feature + Test_SCAStandalone_Telemetry: missing_feature test_automated_login_events.py: - Test_Login_Events: v0.89.0 - Test_Login_Events_Extended: v0.89.0 - Test_V2_Login_Events: missing_feature - Test_V2_Login_Events_Anon: missing_feature + Test_Login_Events: irrelevant (was v0.89.0 but will be replaced by V2) + Test_Login_Events_Extended: irrelevant (was v0.89.0 but will be replaced by V2) + Test_V2_Login_Events: v1.3.0-dev + Test_V2_Login_Events_Anon: v1.3.0-dev Test_V2_Login_Events_RC: missing_feature + Test_V3_Auto_User_Instrum_Mode_Capability: missing_feature + Test_V3_Login_Events: missing_feature + Test_V3_Login_Events_Anon: missing_feature + Test_V3_Login_Events_Blocking: missing_feature + Test_V3_Login_Events_RC: missing_feature + test_automated_user_and_session_tracking.py: + Test_Automated_Session_Blocking: missing_feature + Test_Automated_User_Blocking: missing_feature + Test_Automated_User_Tracking: missing_feature test_blocking_addresses.py: Test_BlockingGraphqlResolvers: missing_feature Test_Blocking_request_body: irrelevant (Php does not accept url encoded entries without key) + Test_Blocking_request_body_multipart: missing_feature Test_Blocking_response_headers: irrelevant (On php it is not possible change the status code once its header is sent) Test_Blocking_response_status: irrelevant (On php it is not possible change the status code once its header is sent) Test_Suspicious_Request_Blocking: missing_feature (v0.86.0 but test is not implemented) test_client_ip.py: Test_StandardTagsClientIp: v0.81.0 + test_fingerprinting.py: + Test_Fingerprinting_Endpoint: missing_feature + Test_Fingerprinting_Endpoint_Capability: missing_feature + Test_Fingerprinting_Header_And_Network: missing_feature + Test_Fingerprinting_Header_Capability: missing_feature + Test_Fingerprinting_Network_Capability: missing_feature + Test_Fingerprinting_Session: missing_feature + Test_Fingerprinting_Session_Capability: missing_feature test_identify.py: Test_Basic: v0.85.0 test_logs.py: Test_StandardizationBlockMode: missing_feature + test_metastruct.py: + Test_SecurityEvents_Appsec_Metastruct_Disabled: irrelevant (no fallback will be implemented) + Test_SecurityEvents_Appsec_Metastruct_Enabled: missing_feature + Test_SecurityEvents_Iast_Metastruct_Disabled: irrelevant (no fallback will be implemented) + Test_SecurityEvents_Iast_Metastruct_Enabled: missing_feature + test_remote_config_rule_changes.py: + Test_BlockingActionChangesWithRemoteConfig: missing_feature + Test_UpdateRuleFileWithRemoteConfig: missing_feature (v0.8.0 but lacks telemetry support) test_reports.py: Test_ExtraTagsFromRule: v0.88.0 Test_Info: v0.68.3 # probably 0.68.2, but was flaky + test_request_blocking.py: + Test_AppSecRequestBlocking: missing_feature # missing version + test_runtime_activation.py: + Test_RuntimeActivation: missing_feature # missing version + Test_RuntimeDeactivation: missing_feature # missing version test_shell_execution.py: Test_ShellExecution: v0.95.0 + test_suspicious_attacker_blocking.py: + Test_Suspicious_Attacker_Blocking: missing_feature test_traces.py: - Test_CollectDefaultRequestHeader: missing_feature - Test_DistributedTraceInfo: missing_feature (test not implemented) - Test_ExternalWafRequestsIdentification: missing_feature + Test_CollectDefaultRequestHeader: v1.0.0 + Test_ExternalWafRequestsIdentification: v1.0.0 test_user_blocking_full_denylist.py: Test_UserBlocking_FullDenylist: v0.86.3 debugger/: - test_debugger.py: - Test_Debugger_Line_Probe_Snaphots: irrelevant - Test_Debugger_Method_Probe_Snaphots: irrelevant - Test_Debugger_Mix_Log_Probe: irrelevant - Test_Debugger_Probe_Statuses: irrelevant + test_debugger_exception_replay.py: + Test_Debugger_Exception_Replay: irrelevant test_debugger_expression_language.py: Test_Debugger_Expression_Language: irrelevant test_debugger_pii.py: Test_Debugger_PII_Redaction: irrelevant + test_debugger_probe_snapshot.py: + Test_Debugger_Probe_Snaphots: irrelevant + test_debugger_probe_status.py: + Test_Debugger_Probe_Statuses: irrelevant integrations/: crossed_integrations/: test_kafka.py: @@ -234,36 +308,62 @@ tests/: Test_DsmRabbitmq_TopicExchange: missing_feature Test_DsmSNS: missing_feature Test_DsmSQS: missing_feature + Test_Dsm_Manual_Checkpoint_Inter_Process: missing_feature + Test_Dsm_Manual_Checkpoint_Intra_Process: missing_feature + test_inferred_proxy.py: + Test_AWS_API_Gateway_Inferred_Span_Creation: missing_feature + test_otel_drop_in.py: + Test_Otel_Drop_In: missing_feature parametric/: test_128_bit_traceids.py: Test_128_Bit_Traceids: v0.84.0 + test_config_consistency.py: + Test_Config_Dogstatsd: missing_feature + Test_Config_RateLimit: v1.5.0 + Test_Config_Tags: missing_feature + Test_Config_TraceAgentURL: v1.4.0 + Test_Config_TraceEnabled: v1.3.0 # Unknown initial version + Test_Config_TraceLogDirectory: missing_feature + Test_Config_UnifiedServiceTagging: v1.5.0 + test_crashtracking.py: + Test_Crashtracking: v1.3.0 test_dynamic_configuration.py: - TestDynamicConfigHeaderTags: missing_feature TestDynamicConfigSamplingRules: missing_feature TestDynamicConfigTracingEnabled: missing_feature TestDynamicConfigV1: missing_feature TestDynamicConfigV1_ServiceTargets: missing_feature TestDynamicConfigV2: missing_feature + test_headers_baggage.py: + Test_Headers_Baggage: missing_feature test_otel_api_interoperability.py: Test_Otel_API_Interoperability: v0.94.0 test_otel_env_vars.py: Test_Otel_Env_Vars: v1.1.0 - test_otel_sdk_interoperability.py: - Test_Otel_SDK_Interoperability: v0.94.0 test_otel_span_methods.py: Test_Otel_Span_Methods: v0.94.0 - test_otel_span_with_w3c.py: - Test_Otel_Span_With_W3c: v0.94.0 + test_otel_span_with_baggage.py: + Test_Otel_Span_With_Baggage: missing_feature test_otel_tracer.py: Test_Otel_Tracer: v0.94.0 + test_parametric_endpoints.py: + Test_Parametric_DDSpan_Add_Link: bug (APMAPI-778) # Adding spans links by parent id does not work as expected + Test_Parametric_DDSpan_Start: bug (APMAPI-778) # Does not support creating a child span from a finished span + Test_Parametric_DDTrace_Baggage: missing_feature (baggage is not supported) + Test_Parametric_DDTrace_Current_Span: bug (APMAPI-778) # current span endpoint should return span and trace id of zero if no span is "active" + Test_Parametric_Otel_Baggage: missing_feature (otel baggage is not supported) + Test_Parametric_Otel_Current_Span: bug (APMAPI-778) # otel current span endpoint should return a span and trace id of zero if no span is "active" + test_partial_flushing.py: + Test_Partial_Flushing: missing_feature test_sampling_delegation.py: Test_Decisionless_Extraction: >- missing_feature (The sampling priority chosen when the trace was extracted without a sampling decision is not consistent with the tracer's configuration. See .) + test_span_events.py: missing_feature test_span_links.py: missing_feature test_telemetry.py: + Test_Consistent_Configs: missing_feature Test_Defaults: missing_feature Test_Environment: missing_feature Test_TelemetryInstallSignature: missing_feature @@ -277,7 +377,7 @@ tests/: Test_Trace_Sampling_Tags_Feb2024_Revision: v0.96.0 Test_Trace_Sampling_With_W3C: missing_feature test_tracer.py: - Test_TracerSCITagging: missing_feature + Test_TracerSCITagging: v1.2.0 test_tracer_flare.py: TestTracerFlareV1: missing_feature remote_config/: @@ -286,9 +386,40 @@ tests/: Test_RemoteConfigurationUpdateSequenceASMDDNoCache: irrelevant (cache is implemented) Test_RemoteConfigurationUpdateSequenceFeaturesNoCache: irrelevant (cache is implemented) Test_RemoteConfigurationUpdateSequenceLiveDebugging: missing_feature - Test_RemoteConfigurationUpdateSequenceLiveDebuggingNoCache: missing_feature + serverless/: + span_pointers/: + aws/: + test_s3_span_pointers.py: + Test_CopyObject: missing_feature + Test_MultipartUpload: missing_feature + Test_PutObject: missing_feature + stats/: + test_miscs.py: + Test_Miscs: missing_feature + test_stats.py: + Test_Client_Stats: missing_feature + test_config_consistency.py: + Test_Config_ClientIPHeaderEnabled_False: v1.5.1 + Test_Config_ClientIPHeader_Configured: v1.4.0 + Test_Config_ClientIPHeader_Precedence: v1.4.0 + Test_Config_ClientTagQueryString_Configured: missing_feature (supports dd_trace_http_url_query_param_allowed instead) + Test_Config_ClientTagQueryString_Empty: v1.2.0 + Test_Config_HttpClientErrorStatuses_Default: missing_feature + Test_Config_HttpClientErrorStatuses_FeatureFlagCustom: missing_feature + Test_Config_HttpServerErrorStatuses_Default: v1.3.0 # Unknown initial version + Test_Config_HttpServerErrorStatuses_FeatureFlagCustom: missing_feature + Test_Config_IntegrationEnabled_False: v1.4.0 + Test_Config_IntegrationEnabled_True: v1.4.0 + Test_Config_ObfuscationQueryStringRegexp_Configured: v1.5.0 + Test_Config_ObfuscationQueryStringRegexp_Empty: v1.5.0 + Test_Config_UnifiedServiceTagging_CustomService: v1.4.0 + Test_Config_UnifiedServiceTagging_Default: v1.4.0 test_distributed.py: Test_DistributedHttp: missing_feature + Test_Span_Links_Flags_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) + Test_Span_Links_From_Conflicting_Contexts: missing_feature + Test_Span_Links_From_Conflicting_Contexts_Datadog_Precedence: missing_feature + Test_Span_Links_Omit_Tracestate_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) test_identify.py: Test_Basic: v0.85.0 Test_Propagate: v0.85.0 @@ -297,20 +428,22 @@ tests/: Test_HeaderTags: v0.68.2 Test_HeaderTags_Colon_Leading: v0.74.0 Test_HeaderTags_Colon_Trailing: v0.74.0 - Test_HeaderTags_Long: missing_feature + Test_HeaderTags_DynamicConfig: missing_feature + Test_HeaderTags_Long: v1.5.0 Test_HeaderTags_Short: v0.74.0 Test_HeaderTags_Whitespace_Header: v0.74.0 - Test_HeaderTags_Whitespace_Tag: missing_feature - Test_HeaderTags_Whitespace_Val_Long: missing_feature + Test_HeaderTags_Whitespace_Tag: v1.5.0 + Test_HeaderTags_Whitespace_Val_Long: v1.5.0 Test_HeaderTags_Whitespace_Val_Short: v0.74.0 test_profiling.py: - Test_Profile: bug (Not receiving profiles) + Test_Profile: missing_feature (profiling seems not to be activated) test_sampling_rates.py: Test_SamplingDecisions: v0.71.0 test_scrubbing.py: Test_UrlQuery: v0.76.0 test_semantic_conventions.py: Test_MetricsStandardTags: v0.83.1 + test_span_events.py: incomplete_test_app (Weblog `/add_event` not implemented) test_standard_tags.py: Test_StandardTagsMethod: v0.75.0 Test_StandardTagsRoute: missing_feature diff --git a/manifests/python.yml b/manifests/python.yml index 842a810b733..5b53d31be33 100644 --- a/manifests/python.yml +++ b/manifests/python.yml @@ -10,23 +10,27 @@ tests/: test_api_security_rc.py: Test_API_Security_RC_ASM_DD_processors: '*': missing_feature - django-poc: v2.6.0dev - fastapi: v2.6.0dev - flask-poc: v2.6.0dev - python3.12: v2.6.0dev - uds-flask: v2.6.0dev - uwsgi-poc: v2.6.0dev + django-poc: v2.6.0 + fastapi: v2.6.0 + flask-poc: v2.6.0 + python3.12: v2.6.0 + uds-flask: v2.6.0 + uwsgi-poc: v2.6.0 Test_API_Security_RC_ASM_DD_scanners: '*': missing_feature - django-poc: v2.6.0dev - fastapi: v2.6.0dev - flask-poc: v2.6.0dev - python3.12: v2.6.0dev - uds-flask: v2.6.0dev - uwsgi-poc: v2.6.0dev - Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: missing_feature # waf does not support it yet + django-poc: v2.6.0 + fastapi: v2.6.0 + flask-poc: v2.6.0 + python3.12: v2.6.0 + uds-flask: v2.6.0 + uwsgi-poc: v2.6.0 + Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: irrelevant (waf does not support it yet) test_apisec_sampling.py: - Test_API_Security_sampling: missing_feature + Test_API_Security_Sampling_Different_Endpoints: v2.6.0 + Test_API_Security_Sampling_Different_Paths: v2.6.0 + Test_API_Security_Sampling_Different_Status: v2.6.0 + Test_API_Security_Sampling_Rate: irrelevant (new api security sampling algorithm implemented) + Test_API_Security_Sampling_With_Delay: v2.6.0 test_schemas.py: Test_Scanners: '*': v2.4.0 @@ -59,96 +63,140 @@ tests/: fastapi: v2.5.0 iast/: sink/: + test_code_injection.py: + TestCodeInjection: missing_feature + TestCodeInjection_StackTrace: missing_feature test_command_injection.py: TestCommandInjection: - '*': v2.10.0.dev - fastapi: missing_feature + '*': v2.10.0 + fastapi: v2.15.0 + TestCommandInjection_StackTrace: v2.19.0.dev test_hardcoded_passwords.py: Test_HardcodedPasswords: missing_feature + Test_HardcodedPasswords_StackTrace: missing_feature test_hardcoded_secrets.py: Test_HardcodedSecrets: missing_feature Test_HardcodedSecretsExtended: missing_feature + Test_HardcodedSecrets_StackTrace: missing_feature test_header_injection.py: TestHeaderInjection: - '*': v2.10.0dev + '*': v2.10.0 + fastapi: missing_feature + TestHeaderInjectionExclusionAccessControlAllow: missing_feature + TestHeaderInjectionExclusionContentEncoding: missing_feature + TestHeaderInjectionExclusionPragma: missing_feature + TestHeaderInjectionExclusionTransferEncoding: missing_feature + TestHeaderInjection_StackTrace: + '*': v2.19.0.dev fastapi: missing_feature test_hsts_missing_header.py: Test_HstsMissingHeader: missing_feature + Test_HstsMissingHeader_StackTrace: missing_feature test_insecure_auth_protocol.py: Test_InsecureAuthProtocol: missing_feature + Test_InsecureAuthProtocol_StackTrace: missing_feature test_insecure_cookie.py: TestInsecureCookie: '*': v1.19.0 - fastapi: missing_feature + fastapi: v2.16.0-dev + TestInsecureCookieNameFilter: missing_feature + TestInsecureCookie_StackTrace: missing_feature test_ldap_injection.py: TestLDAPInjection: missing_feature + TestLDAPInjection_StackTrace: missing_feature test_no_httponly_cookie.py: TestNoHttponlyCookie: '*': v1.19.0 - fastapi: missing_feature + fastapi: v2.16.0-dev + TestNoHttponlyCookieNameFilter: missing_feature + TestNoHttponlyCookie_StackTrace: missing_feature test_no_samesite_cookie.py: TestNoSamesiteCookie: '*': v1.19.0 - fastapi: missing_feature + fastapi: v2.16.0-dev + TestNoSamesiteCookieNameFilter: missing_feature + TestNoSamesiteCookie_StackTrace: missing_feature test_nosql_mongodb_injection.py: TestNoSqlMongodbInjection: missing_feature + TestNoSqlMongodbInjection_StackTrace: missing_feature test_path_traversal.py: TestPathTraversal: - '*': v2.10.0dev - fastapi: missing_feature + '*': v2.10.0 + fastapi: v2.15.0 + TestPathTraversal_StackTrace: v2.19.0.dev test_reflection_injection.py: TestReflectionInjection: missing_feature + TestReflectionInjection_StackTrace: missing_feature test_sql_injection.py: TestSqlInjection: django-poc: v1.18.0 - fastapi: missing_feature + fastapi: v2.15.0 flask-poc: v1.18.0 pylons: missing_feature python3.12: v1.18.0 + TestSqlInjection_StackTrace: v2.19.0.dev test_ssrf.py: TestSSRF: - '*': v2.10.0dev - fastapi: missing_feature + '*': v2.10.0 + fastapi: v2.15.0 + TestSSRF_StackTrace: v2.19.0.dev + test_template_injection.py: + TestTemplateInjection: missing_feature test_trust_boundary_violation.py: Test_TrustBoundaryViolation: missing_feature + Test_TrustBoundaryViolation_StackTrace: missing_feature + test_untrusted_deserialization.py: + TestUntrustedDeserialization: missing_feature + TestUntrustedDeserialization_StackTrace: missing_feature test_unvalidated_redirect.py: TestUnvalidatedHeader: missing_feature + TestUnvalidatedHeader_StackTrace: missing_feature TestUnvalidatedRedirect: missing_feature + TestUnvalidatedRedirect_StackTrace: missing_feature test_unvalidated_redirect_forward.py: TestUnvalidatedForward: missing_feature + TestUnvalidatedForward_StackTrace: missing_feature test_weak_cipher.py: TestWeakCipher: '*': v1.18.0 - fastapi: missing_feature + fastapi: v2.15.0 + TestWeakCipher_StackTrace: v2.19.0.dev test_weak_hash.py: + TestDeduplication: + '*': v1.18.0 TestWeakHash: '*': v1.18.0 + TestWeakHash_StackTrace: v2.19.0.dev test_weak_randomness.py: TestWeakRandomness: '*': v2.0.0 + TestWeakRandomness_StackTrace: v2.19.0.dev test_xcontent_sniffing.py: Test_XContentSniffing: missing_feature + Test_XContentSniffing_StackTrace: missing_feature test_xpath_injection.py: TestXPathInjection: missing_feature + TestXPathInjection_StackTrace: missing_feature test_xss.py: TestXSS: missing_feature + TestXSS_StackTrace: missing_feature source/: test_body.py: TestRequestBody: django-poc: v1.20.0 - fastapi: missing_feature - flask-poc: v1.20.0 + fastapi: v2.14.0 + flask-poc: v2.13.0 python3.12: v1.20.0 uds-flask: v1.20.0 uwsgi-poc: v1.20.0 test_cookie_name.py: TestCookieName: - '*': v2.10.0dev - fastapi: missing_feature + '*': v2.10.0 + fastapi: v2.13.0 test_cookie_value.py: TestCookieValue: - '*': v2.10.0dev - fastapi: missing_feature + '*': v2.10.0 + fastapi: v2.13.0 test_graphql_resolver.py: TestGraphqlResolverArgument: missing_feature test_header_name.py: @@ -158,7 +206,7 @@ tests/: test_header_value.py: TestHeaderValue: '*': v1.18.0 - fastapi: missing_feature + fastapi: v2.13.0 test_kafka_key.py: TestKafkaKey: missing_feature test_kafka_value.py: @@ -175,303 +223,413 @@ tests/: uwsgi-poc: missing_feature test_parameter_value.py: TestParameterValue: - '*': v2.9.0.dev - fastapi: missing_feature + '*': v2.9.0 + fastapi: v2.13.0 test_path.py: - TestPath: missing_feature + TestPath: + '*': v2.9.0 + fastapi: v2.13.0 + flask-poc: v2.13.0 + uds-flask: v2.13.0 + uwsgi-poc: v2.13.0 + test_path_parameter.py: + TestPathParameter: + '*': v2.9.0 + fastapi: v2.13.0 + flask-poc: v2.13.0 + uds-flask: v2.13.0 + uwsgi-poc: v2.13.0 + test_sql_row.py: + TestSqlRow: missing_feature test_uri.py: TestURI: missing_feature rasp/: + test_cmdi.py: + Test_Cmdi_BodyJson: missing_feature + Test_Cmdi_BodyUrlEncoded: missing_feature + Test_Cmdi_BodyXml: missing_feature + Test_Cmdi_Capability: missing_feature + Test_Cmdi_Mandatory_SpanTags: missing_feature + Test_Cmdi_Optional_SpanTags: missing_feature + Test_Cmdi_Rules_Version: v2.18.0.dev + Test_Cmdi_StackTrace: missing_feature + Test_Cmdi_Telemetry: missing_feature + Test_Cmdi_Telemetry_Variant_Tag: missing_feature + Test_Cmdi_UrlQuery: missing_feature + Test_Cmdi_Waf_Version: v2.18.0.dev test_lfi.py: - Test_Lfi_BodyJson: v2.10.0.dev - Test_Lfi_BodyUrlEncoded: v2.10.0.dev - Test_Lfi_BodyXml: v2.10.0.dev - Test_Lfi_UrlQuery: v2.10.0.dev - test_span_tags.py: - Test_Mandatory_SpanTags: v2.10.0.dev - Test_Optional_SpanTags: v2.10.0.dev + Test_Lfi_BodyJson: v2.10.0 + Test_Lfi_BodyUrlEncoded: v2.10.0 + Test_Lfi_BodyXml: v2.10.0 + Test_Lfi_Capability: v2.11.0 + Test_Lfi_Mandatory_SpanTags: v2.10.0 + Test_Lfi_Optional_SpanTags: v2.10.0 + Test_Lfi_RC_CustomAction: v2.14.0 + Test_Lfi_Rules_Version: v2.18.0.dev + Test_Lfi_StackTrace: v2.10.0 + Test_Lfi_Telemetry: v2.10.0 + Test_Lfi_UrlQuery: v2.10.0 + Test_Lfi_Waf_Version: v2.15.0 + test_shi.py: + Test_Shi_BodyJson: v2.11.0-rc2 + Test_Shi_BodyUrlEncoded: v2.11.0-rc2 + Test_Shi_BodyXml: v2.11.0-rc2 + Test_Shi_Capability: v2.11.0 + Test_Shi_Mandatory_SpanTags: v2.11.0-rc2 + Test_Shi_Optional_SpanTags: v2.11.0-rc2 + Test_Shi_Rules_Version: v2.15.0 + Test_Shi_StackTrace: v2.11.0-rc2 + Test_Shi_Telemetry: v2.11.0-rc2 + Test_Shi_Telemetry_Variant_Tag: missing_feature + Test_Shi_UrlQuery: v2.11.0-rc2 + Test_Shi_Waf_Version: v2.15.0 test_sqli.py: - Test_Sqli_BodyJson: v2.10.0.dev - Test_Sqli_BodyUrlEncoded: v2.10.0.dev - Test_Sqli_BodyXml: v2.10.0.dev - Test_Sqli_UrlQuery: v2.10.0.dev + Test_Sqli_BodyJson: v2.10.0 + Test_Sqli_BodyUrlEncoded: v2.10.0 + Test_Sqli_BodyXml: v2.10.0 + Test_Sqli_Capability: v2.11.0 + Test_Sqli_Mandatory_SpanTags: v2.10.0 + Test_Sqli_Optional_SpanTags: v2.10.0 + Test_Sqli_Rules_Version: v2.16.0 + Test_Sqli_StackTrace: v2.10.0 + Test_Sqli_Telemetry: v2.10.0 + Test_Sqli_UrlQuery: v2.10.0 + Test_Sqli_Waf_Version: v2.15.0 test_ssrf.py: - Test_Ssrf_BodyJson: v2.10.0.dev - Test_Ssrf_BodyUrlEncoded: v2.10.0.dev - Test_Ssrf_BodyXml: v2.10.0.dev - Test_Ssrf_UrlQuery: v2.10.0.dev - test_stack_traces.py: - Test_StackTrace: v2.10.0.dev + Test_Ssrf_BodyJson: v2.10.0 + Test_Ssrf_BodyUrlEncoded: v2.10.0 + Test_Ssrf_BodyXml: v2.10.0 + Test_Ssrf_Capability: v2.11.0 + Test_Ssrf_Mandatory_SpanTags: v2.10.0 + Test_Ssrf_Optional_SpanTags: v2.10.0 + Test_Ssrf_Rules_Version: v2.16.0 + Test_Ssrf_StackTrace: v2.10.0 + Test_Ssrf_Telemetry: v2.10.0 + Test_Ssrf_UrlQuery: v2.10.0 + Test_Ssrf_Waf_Version: v2.15.0 waf/: test_addresses.py: Test_BodyJson: - '*': v1.4.0rc1.dev - fastapi: v2.4.0.dev1 + '*': v1.4.0-rc1 + fastapi: v2.4.0 Test_BodyRaw: '*': missing_feature django-poc: v1.5.2 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 python3.12: v1.5.2 Test_BodyUrlEncoded: - '*': v1.4.0rc1.dev - fastapi: v2.4.0.dev1 + '*': v1.4.0-rc1 + fastapi: v2.4.0 Test_BodyXml: - '*': v1.5.0rc1.dev - fastapi: v2.4.0.dev1 - Test_ClientIP: missing_feature (v1.5.0rc1.dev but test is not implemented) + '*': v1.5.0-rc1 + fastapi: v2.4.0 Test_Cookies: - django-poc: v1.1.0rc2.dev - fastapi: v2.4.0.dev1 - flask-poc: v1.4.0rc1.dev - pylons: v1.1.0rc2.dev - python3.12: v1.1.0rc2.dev - uds-flask: v1.4.0rc1.dev + django-poc: v1.1.0-rc2 + fastapi: v2.4.0 + flask-poc: v1.4.0-rc1 + pylons: v1.1.0-rc2 + python3.12: v1.1.0-rc2 + uds-flask: v1.4.0-rc1 uwsgi-poc: v1.16.1 Test_FullGrpc: missing_feature Test_GraphQL: missing_feature Test_GrpcServerMethod: missing_feature Test_Headers: v1.6 - Test_Lambda: missing_feature - Test_Method: missing_feature Test_PathParams: - django-poc: v1.1.0rc2.dev - fastapi: v2.4.0.dev1 - flask-poc: v1.4.0rc1.dev - pylons: v1.1.0rc2.dev - python3.12: v1.1.0rc2.dev - uds-flask: v1.4.0rc1.dev + django-poc: v1.1.0-rc2 + fastapi: v2.4.0 + flask-poc: v1.4.0-rc1 + pylons: v1.1.0-rc2 + python3.12: v1.1.0-rc2 + uds-flask: v1.4.0-rc1 uwsgi-poc: v1.5.2 Test_ResponseStatus: '*': v0.58.5 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_UrlQuery: '*': v1.2.1 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_UrlQueryKey: '*': v1.2.1 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_UrlRaw: '*': v0.58.5 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_gRPC: missing_feature test_blocking.py: Test_Blocking: '*': v1.16.1 django-poc: v1.10 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 flask-poc: v1.10 - Test_Blocking_strip_response_headers: v2.10.0.dev + Test_Blocking_strip_response_headers: v2.10.0 Test_CustomBlockingResponse: - '*': v1.20.0.dev - fastapi: v2.4.0.dev1 + '*': v1.20.0 + fastapi: v2.4.0 test_custom_rules.py: Test_CustomRules: '*': v1.16.1 django-poc: v1.12 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 flask-poc: v1.12 test_exclusions.py: Test_Exclusions: '*': v1.16.1 django-poc: v1.12 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 flask-poc: v1.12 test_miscs.py: - Test_404: v1.1.0rc2.dev + Test_404: v1.1.0-rc2 Test_CorrectOptionProcessing: '*': v1.1.0 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_MultipleAttacks: '*': v1.2.1 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_MultipleHighlight: '*': v1.2.1 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 test_reports.py: Test_Monitoring: - '*': v1.5.0rc1.dev - fastapi: v2.4.0.dev1 + '*': v1.5.0-rc1 + fastapi: v2.4.0 test_rules.py: Test_CommandInjection: '*': v1.2.1 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_DiscoveryScan: '*': v0.58.5 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_HttpProtocol: '*': v1.2.1 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_JavaCodeInjection: '*': v1.2.1 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_JsInjection: '*': v1.2.1 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_LFI: - '*': v2.4.0.dev1 + '*': v2.4.0 flask-poc: v1.5.2 uds-flask: v1.5.2 - uwsgi-poc: v2.9.0.dev + uwsgi-poc: v2.9.0 Test_NoSqli: '*': v1.2.1 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_PhpCodeInjection: '*': v1.2.1 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_RFI: '*': v1.2.1 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_SQLI: '*': v1.3.0 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_SSRF: '*': v1.2.1 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_Scanners: '*': v1.2.1 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 Test_XSS: '*': v1.3.0 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 test_telemetry.py: Test_TelemetryMetrics: '*': v1.14.0 - fastapi: v2.4.0.dev1 - test_PII.py: - Test_Scrubbing: missing_feature + fastapi: v2.4.0 test_alpha.py: Test_Basic: - '*': v1.1.0rc2.dev - fastapi: v2.4.0.dev1 + '*': v1.1.0-rc2 + fastapi: v2.4.0 test_asm_standalone.py: Test_AppSecStandalone_UpstreamPropagation: - '*': v2.10.0-rc1 - uwsgi-poc: bug + '*': v2.12.3 + uwsgi-poc: v2.17.1 + Test_IastStandalone_UpstreamPropagation: + '*': v2.18.0.dev + Test_SCAStandalone_Telemetry: v2.19.0.dev test_automated_login_events.py: - Test_Login_Events: irrelevant (was v2.10.0.dev but will be replaced by V2) - Test_Login_Events_Extended: irrelevant (was v2.10.0.dev but will be replaced by V2) - Test_V2_Login_Events: missing_feature - Test_V2_Login_Events_Anon: missing_feature - Test_V2_Login_Events_RC: missing_feature + Test_Login_Events: irrelevant (was v2.10.0 but will be replaced by V2) + Test_Login_Events_Extended: irrelevant (was v2.10.0 but will be replaced by V2) + Test_V2_Login_Events: v2.11.0 + Test_V2_Login_Events_Anon: v2.11.0 + Test_V2_Login_Events_RC: v2.11.0 + Test_V3_Auto_User_Instrum_Mode_Capability: missing_feature + Test_V3_Login_Events: missing_feature + Test_V3_Login_Events_Anon: missing_feature + Test_V3_Login_Events_Blocking: missing_feature + Test_V3_Login_Events_RC: missing_feature + test_automated_user_and_session_tracking.py: + Test_Automated_Session_Blocking: missing_feature + Test_Automated_User_Blocking: missing_feature + Test_Automated_User_Tracking: missing_feature test_blocking_addresses.py: - Test_BlockingAddresses: + Test_BlockingGraphqlResolvers: missing_feature + Test_Blocking_client_ip: '*': v1.16.1 django-poc: v1.10 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 flask-poc: v1.10 - Test_BlockingGraphqlResolvers: missing_feature Test_Blocking_request_body: '*': v1.16.1 django-poc: v1.10 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 + flask-poc: v1.10 + Test_Blocking_request_body_multipart: + '*': v1.16.1 + django-poc: v1.10 + fastapi: v2.4.0 flask-poc: v1.10 Test_Blocking_request_cookies: '*': v1.16.1 django-poc: v1.10 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 flask-poc: v1.10 Test_Blocking_request_headers: '*': v1.16.1 django-poc: v1.10 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 flask-poc: v1.10 Test_Blocking_request_method: '*': v1.16.1 django-poc: v1.10 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 flask-poc: v1.10 Test_Blocking_request_path_params: '*': v1.16.1 django-poc: v1.10 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 flask-poc: v1.13 Test_Blocking_request_query: '*': v1.16.1 django-poc: v1.10 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 flask-poc: v1.10 Test_Blocking_request_uri: '*': v1.16.1 django-poc: v1.15 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 flask-poc: v1.15 Test_Blocking_response_headers: '*': v1.16.1 django-poc: v1.10 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 flask-poc: v1.10 Test_Blocking_response_status: '*': v1.16.1 django-poc: v1.10 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 flask-poc: v1.10 - Test_Suspicious_Request_Blocking: missing_feature (v1.20.0, but test is not implemented) + Test_Blocking_user_id: + '*': v1.16.1 + django-poc: v1.10 + fastapi: v2.4.0 + flask-poc: v1.10 + Test_Suspicious_Request_Blocking: v2.4.0 test_client_ip.py: Test_StandardTagsClientIp: v1.5.0 test_conf.py: Test_ConfigurationVariables: '*': v1.1.2 - fastapi: v2.4.0.dev1 - Test_RuleSet_1_3_1: - '*': v1.2.1 - fastapi: v2.4.0.dev1 - Test_StaticRuleSet: missing_feature + fastapi: v2.4.0 test_customconf.py: - Test_ConfRuleSet: v1.1.0rc2.dev - Test_NoLimitOnWafRules: v1.1.0rc2.dev + Test_ConfRuleSet: v1.1.0-rc2 + Test_NoLimitOnWafRules: v1.1.0-rc2 test_event_tracking.py: Test_CustomEvent: v1.10.0 Test_UserLoginFailureEvent: - '*': v2.10.0.dev + '*': v2.10.0 Test_UserLoginSuccessEvent: - '*': v2.10.0.dev + '*': v2.10.0 + test_fingerprinting.py: + Test_Fingerprinting_Endpoint: v2.11.0 + Test_Fingerprinting_Endpoint_Capability: v2.11.0 + Test_Fingerprinting_Header_And_Network: v2.11.0 + Test_Fingerprinting_Header_Capability: v2.11.0 + Test_Fingerprinting_Network_Capability: v2.11.0 + Test_Fingerprinting_Session: v2.17.0.dev + Test_Fingerprinting_Session_Capability: v2.17.0.dev test_identify.py: - Test_Basic: v1.5.0rc1.dev + Test_Basic: v1.5.0-rc1 test_ip_blocking_full_denylist.py: - Test_AppSecIPBlockingFullDenylist: v1.10.0 # partially missing_feature (Python supported denylists of 2500 entries but it fails to block this those 15000) + Test_AppSecIPBlockingFullDenylist: v2.11.0 test_logs.py: Test_Standardization: missing_feature Test_StandardizationBlockMode: missing_feature + test_metastruct.py: + Test_SecurityEvents_Appsec_Metastruct_Disabled: irrelevant (no fallback will be implemented) + Test_SecurityEvents_Appsec_Metastruct_Enabled: missing_feature + Test_SecurityEvents_Iast_Metastruct_Disabled: irrelevant (no fallback will be implemented) + Test_SecurityEvents_Iast_Metastruct_Enabled: missing_feature + test_rate_limiter.py: + Test_Main: v2.0.0 + test_remote_config_rule_changes.py: + Test_BlockingActionChangesWithRemoteConfig: v2.10.1 + Test_UpdateRuleFileWithRemoteConfig: v2.16.0-rc (v2.11.0 but added telemetry and span tag support in 2.16) test_reports.py: Test_ExtraTagsFromRule: v1.14.0 - Test_HttpClientIP: v1.5.0rc1.dev - Test_Info: v1.1.0rc2.dev - Test_RequestHeaders: v1.1.0rc2.dev - Test_StatusCode: v1.1.0rc2.dev + Test_Info: v1.1.0-rc2 + Test_RequestHeaders: v1.1.0-rc2 + Test_StatusCode: v1.1.0-rc2 test_request_blocking.py: Test_AppSecRequestBlocking: '*': v1.10.0 - fastapi: v2.4.0.dev1 + fastapi: v2.4.0 test_runtime_activation.py: - Test_RuntimeActivation: missing_feature + Test_RuntimeActivation: v2.10.1 + Test_RuntimeDeactivation: v2.10.1 test_shell_execution.py: Test_ShellExecution: missing_feature + test_suspicious_attacker_blocking.py: + Test_Suspicious_Attacker_Blocking: v2.11.0-rc test_traces.py: Test_AppSecEventSpanTags: v0.58.5 Test_AppSecObfuscator: - '*': v1.5.0rc1.dev - fastapi: v2.6.0.dev1 - Test_CollectDefaultRequestHeader: v2.9.0.dev40 + '*': v1.5.0-rc1 + fastapi: v2.6.0 + Test_CollectDefaultRequestHeader: v2.9.040 Test_CollectRespondHeaders: - '*': v1.4.0rc1.dev - fastapi: v2.4.0.dev1 - Test_DistributedTraceInfo: missing_feature (test not implemented) - Test_ExternalWafRequestsIdentification: v2.9.0.dev1 - Test_RetainTraces: v1.1.0rc2.dev + '*': v1.4.0-rc1 + fastapi: v2.4.0 + Test_ExternalWafRequestsIdentification: v2.9.0 + Test_RetainTraces: v1.1.0-rc2 test_user_blocking_full_denylist.py: - Test_UserBlocking_FullDenylist: v1.10.0 # partially missing_feature missing_feature (Python supported denylists of 2500 entries but it fails to block this those 15000) + Test_UserBlocking_FullDenylist: v2.11.0 test_versions.py: Test_Events: v0.58.5 debugger/: - test_debugger.py: - Test_Debugger_Line_Probe_Snaphots: missing_feature - Test_Debugger_Method_Probe_Snaphots: missing_feature - Test_Debugger_Mix_Log_Probe: missing_feature - Test_Debugger_Probe_Statuses: missing_feature + test_debugger_exception_replay.py: + Test_Debugger_Exception_Replay: + '*': missing_feature + flask-poc: v2.11.0 + uds-flask: v2.11.0 + uwsgi-poc: v2.11.0 test_debugger_expression_language.py: - Test_Debugger_Expression_Language: missing_feature + Test_Debugger_Expression_Language: + '*': missing_feature + flask-poc: v2.11.0 + uds-flask: v2.11.0 + uwsgi-poc: v2.11.0 test_debugger_pii.py: - Test_Debugger_PII_Redaction: missing_feature + Test_Debugger_PII_Redaction: + '*': missing_feature + flask-poc: v2.11.0 + uds-flask: v2.11.0 + uwsgi-poc: v2.11.0 + test_debugger_probe_snapshot.py: + Test_Debugger_Probe_Snaphots: + '*': missing_feature + flask-poc: v2.11.0 + uds-flask: v2.11.0 + uwsgi-poc: v2.11.0 + test_debugger_probe_status.py: + Test_Debugger_Probe_Statuses: + '*': missing_feature + flask-poc: v2.11.0 + uds-flask: v2.11.0 + uwsgi-poc: v2.11.0 integrations/: crossed_integrations/: test_kafka.py: @@ -513,49 +671,57 @@ tests/: flask-poc: v0.1 uds-flask: v2.9.0 uwsgi-poc: v2.9.0 - Test_Dbm_Comment_Batch_Python_Aiomysql: + Test_Dbm_Comment_Batch_Python_Aiomysql: '*': missing_feature (Missing on weblog) flask-poc: v2.9.0 uds-flask: v2.9.0 uwsgi-poc: v2.9.0 - Test_Dbm_Comment_Batch_Python_MysqlConnector: + Test_Dbm_Comment_Batch_Python_MysqlConnector: '*': missing_feature (Missing on weblog) flask-poc: v2.9.0 - Test_Dbm_Comment_Batch_Python_Mysqldb: + uds-flask: v2.9.0 + uwsgi-poc: v2.9.0 + Test_Dbm_Comment_Batch_Python_Mysqldb: '*': missing_feature (Missing on weblog) flask-poc: v2.9.0 - Test_Dbm_Comment_Batch_Python_Psycopg: + uds-flask: v2.9.0 + uwsgi-poc: v2.9.0 + Test_Dbm_Comment_Batch_Python_Psycopg: '*': missing_feature (Missing on weblog) flask-poc: v2.8.0 uds-flask: v2.9.0 uwsgi-poc: v2.9.0 - Test_Dbm_Comment_Batch_Python_Pymysql: + Test_Dbm_Comment_Batch_Python_Pymysql: '*': missing_feature (Missing on weblog) flask-poc: v2.9.0 uds-flask: v2.9.0 uwsgi-poc: v2.9.0 - Test_Dbm_Comment_Python_Aiomysql: + Test_Dbm_Comment_Python_Aiomysql: '*': missing_feature (Missing on weblog) flask-poc: v2.9.0 uds-flask: v2.9.0 uwsgi-poc: v2.9.0 - Test_Dbm_Comment_Python_Asyncpg: + Test_Dbm_Comment_Python_Asyncpg: '*': missing_feature (Missing on weblog) flask-poc: v2.9.0 uds-flask: v2.9.0 uwsgi-poc: v2.9.0 - Test_Dbm_Comment_Python_MysqlConnector: + Test_Dbm_Comment_Python_MysqlConnector: '*': missing_feature (Missing on weblog) flask-poc: v2.9.0 - Test_Dbm_Comment_Python_Mysqldb: + uds-flask: v2.9.0 + uwsgi-poc: v2.9.0 + Test_Dbm_Comment_Python_Mysqldb: '*': missing_feature (Missing on weblog) flask-poc: v2.9.0 - Test_Dbm_Comment_Python_Psycopg: + uds-flask: v2.9.0 + uwsgi-poc: v2.9.0 + Test_Dbm_Comment_Python_Psycopg: '*': missing_feature (Missing on weblog) flask-poc: v2.8.0 uds-flask: v2.9.0 uwsgi-poc: v2.9.0 - Test_Dbm_Comment_Python_Pymysql: + Test_Dbm_Comment_Python_Pymysql: '*': missing_feature (Missing on weblog) flask-poc: v2.9.0 uds-flask: v2.9.0 @@ -563,17 +729,17 @@ tests/: test_dsm.py: Test_DsmContext_Extraction_Base64: '*': irrelevant - flask-poc: v2.8.0.dev + flask-poc: v2.8.0 Test_DsmContext_Injection_Base64: '*': irrelevant - flask-poc: v2.8.0.dev + flask-poc: v2.8.0 Test_DsmHttp: missing_feature Test_DsmKafka: '*': irrelevant - flask-poc: v1.20.3 + flask-poc: v2.16.0 Test_DsmKinesis: '*': irrelevant - flask-poc: v2.8.0.dev + flask-poc: v2.8.0 Test_DsmRabbitmq: '*': irrelevant flask-poc: v2.6.0 @@ -589,20 +755,44 @@ tests/: Test_DsmSQS: '*': irrelevant flask-poc: v1.16.0 + Test_Dsm_Manual_Checkpoint_Inter_Process: + '*': irrelevant + flask-poc: v2.8.0 + Test_Dsm_Manual_Checkpoint_Intra_Process: + '*': irrelevant + flask-poc: v2.8.0 + test_inferred_proxy.py: + Test_AWS_API_Gateway_Inferred_Span_Creation: missing_feature + test_otel_drop_in.py: + Test_Otel_Drop_In: missing_feature + k8s_lib_injection/: + test_k8s_manual_inject.py: + TestAdmisionControllerProfiling: v2.12.2 parametric/: test_128_bit_traceids.py: Test_128_Bit_Traceids: v2.6.0 + test_config_consistency.py: + Test_Config_Dogstatsd: missing_feature + Test_Config_RateLimit: v2.15.0 + Test_Config_Tags: missing_feature + Test_Config_TraceAgentURL: v2.0.0 + Test_Config_TraceEnabled: v2.12.2 + Test_Config_TraceLogDirectory: missing_feature + Test_Config_UnifiedServiceTagging: v2.12.2 + test_crashtracking.py: + Test_Crashtracking: v2.11.2 test_dynamic_configuration.py: - TestDynamicConfigHeaderTags: flaky (failure 2.8.0/2.9.0.dev) - TestDynamicConfigSamplingRules: v2.9.0dev - TestDynamicConfigTracingEnabled: flaky (failure 2.8.0/2.9.0.dev) + TestDynamicConfigSamplingRules: v2.9.0 + TestDynamicConfigTracingEnabled: flaky (APMAPI-734) TestDynamicConfigV1: missing_feature (failure 2.8.0) TestDynamicConfigV1_ServiceTargets: missing_feature (failure 2.8.0) - TestDynamicConfigV2: flaky (failure 2.8.0/2.9.0.dev) + TestDynamicConfigV2: flaky (APMAPI-734) test_headers_b3.py: Test_Headers_B3: v2.8.0 test_headers_b3multi.py: Test_Headers_B3multi: v2.8.0 + test_headers_baggage.py: + Test_Headers_Baggage: v2.16.0 test_headers_datadog.py: Test_Headers_Datadog: v2.8.0 test_headers_none.py: @@ -619,36 +809,39 @@ tests/: Test_Otel_API_Interoperability: missing_feature test_otel_env_vars.py: Test_Otel_Env_Vars: v2.9.0 - test_otel_sdk_interoperability.py: - Test_Otel_SDK_Interoperability: missing_feature test_otel_span_methods.py: Test_Otel_Span_Methods: v2.8.0 - test_otel_span_with_w3c.py: - Test_Otel_Span_With_W3c: v2.8.0 + test_otel_span_with_baggage.py: + Test_Otel_Span_With_Baggage: v2.18.0 test_otel_tracer.py: Test_Otel_Tracer: v2.8.0 + test_parametric_endpoints.py: + Test_Parametric_DDTrace_Baggage: v2.16.0 + Test_Parametric_Otel_Baggage: v2.16.0 test_partial_flushing.py: - Test_Partial_Flushing: flaky (failure 2.8.0/2.9.0.dev) + Test_Partial_Flushing: flaky (APMAPI-734) test_sampling_delegation.py: Test_Decisionless_Extraction: v2.8.0 test_sampling_span_tags.py: Test_Sampling_Span_Tags: v2.8.0 + test_span_events.py: missing_feature test_span_links.py: Test_Span_Links: v2.3.0 test_span_sampling.py: Test_Span_Sampling: v2.8.0 test_telemetry.py: - Test_Defaults: v2.9.0.dev + Test_Consistent_Configs: missing_feature + Test_Defaults: v2.9.0 Test_Environment: v2.8.0 Test_TelemetryInstallSignature: v2.5.0 - Test_TelemetrySCAEnvVar: v2.9.0.dev + Test_TelemetrySCAEnvVar: v2.9.0 test_trace_sampling.py: Test_Trace_Sampling_Basic: v1.9.0 # actual version unknown Test_Trace_Sampling_Globs: v2.8.0 Test_Trace_Sampling_Globs_Feb2024_Revision: v2.8.0 Test_Trace_Sampling_Resource: v2.8.0 Test_Trace_Sampling_Tags: v2.8.0 - Test_Trace_Sampling_Tags_Feb2024_Revision: v2.9.0.dev + Test_Trace_Sampling_Tags_Feb2024_Revision: v2.9.0 Test_Trace_Sampling_With_W3C: v2.8.0 test_tracer.py: Test_Tracer: v2.8.0 @@ -658,27 +851,74 @@ tests/: TestTracerFlareV1: missing_feature (failure 2.8.0) remote_config/: test_remote_configuration.py: - Test_RemoteConfigurationExtraServices: v2.1.0.dev - Test_RemoteConfigurationUpdateSequenceASMDD: v2.9.0.dev + Test_RemoteConfigurationExtraServices: v2.1.0 + Test_RemoteConfigurationUpdateSequenceASMDD: v2.9.0 Test_RemoteConfigurationUpdateSequenceASMDDNoCache: missing_feature Test_RemoteConfigurationUpdateSequenceFeatures: v1.7.4 Test_RemoteConfigurationUpdateSequenceFeaturesNoCache: irrelevant (cache is implemented) - Test_RemoteConfigurationUpdateSequenceLiveDebugging: v2.8.0.dev - Test_RemoteConfigurationUpdateSequenceLiveDebuggingNoCache: missing_feature + Test_RemoteConfigurationUpdateSequenceLiveDebugging: v2.8.0 + serverless/: + span_pointers/: + aws/: + test_s3_span_pointers.py: + # NOTE: fastapi-based async things don't play well with moto + Test_CopyObject: + '*': missing_feature + django-poc: v2.15.0 + flask-poc: v2.15.0 + python3.12: v2.15.0 + Test_MultipartUpload: + '*': missing_feature + django-poc: v2.15.0 + flask-poc: v2.15.0 + python3.12: v2.15.0 + Test_PutObject: + '*': missing_feature + django-poc: v2.14.0 + flask-poc: v2.14.0 + python3.12: v2.14.0 + stats/: + test_miscs.py: + Test_Miscs: missing_feature + test_config_consistency.py: + Test_Config_ClientIPHeaderEnabled_False: v2.17.3 + Test_Config_ClientIPHeader_Configured: v2.12.0 + Test_Config_ClientIPHeader_Precedence: v2.12.0 + Test_Config_ClientTagQueryString_Configured: v2.15.0 + Test_Config_ClientTagQueryString_Empty: v2.12.0 + Test_Config_HttpClientErrorStatuses_Default: missing_feature + Test_Config_HttpClientErrorStatuses_FeatureFlagCustom: missing_feature (xpassing but should fail, this environment variable is not supported) + Test_Config_HttpServerErrorStatuses_Default: v2.12.0 + Test_Config_HttpServerErrorStatuses_FeatureFlagCustom: v2.15.0 + Test_Config_IntegrationEnabled_False: + '*': irrelevant (kafka endpoint is not implemented) + flask-poc: v2.0.0 + Test_Config_IntegrationEnabled_True: + '*': irrelevant (kafka endpoint is not implemented) + flask-poc: v2.0.0 + Test_Config_ObfuscationQueryStringRegexp_Configured: v2.0.0 + Test_Config_ObfuscationQueryStringRegexp_Empty: v2.15.0 + Test_Config_UnifiedServiceTagging_CustomService: v2.0.0 + Test_Config_UnifiedServiceTagging_Default: v2.0.0 test_data_integrity.py: Test_LibraryHeaders: v2.7.0 test_distributed.py: Test_DistributedHttp: '*': missing_feature (Missing on weblog) - flask-poc: v1.5.0rc2.dev # actual version unknown + flask-poc: v1.5.0-rc2 # actual version unknown + Test_Span_Links_Flags_From_Conflicting_Contexts: v2.17.0 + Test_Span_Links_From_Conflicting_Contexts: v2.17.0 + Test_Span_Links_From_Conflicting_Contexts_Datadog_Precedence: v2.17.0 + Test_Span_Links_Omit_Tracestate_From_Conflicting_Contexts: v2.17.0 test_identify.py: - Test_Basic: v1.5.0rc1.dev + Test_Basic: v1.5.0-rc1 Test_Propagate: v1.9.0 - Test_Propagate_Legacy: v1.5.0rc1.dev + Test_Propagate_Legacy: v1.5.0-rc1 test_library_conf.py: Test_HeaderTags: v0.53 Test_HeaderTags_Colon_Leading: v1.2.1 # actual version unknown - Test_HeaderTags_Colon_Trailing: v2.8.0.dev + Test_HeaderTags_Colon_Trailing: v2.8.0 + Test_HeaderTags_DynamicConfig: flaky (APMAPI-734) Test_HeaderTags_Long: v1.2.1 Test_HeaderTags_Short: missing_feature Test_HeaderTags_Whitespace_Header: missing_feature @@ -688,25 +928,29 @@ tests/: test_profiling.py: Test_Profile: '*': v0.1 # actual version unknown - python3.12: v2.1.0.dev + python3.12: v2.1.0 + test_sampling_rates.py: + Test_SamplingDecisions: v2.8.0 + Test_SamplingRates: v2.8.0 test_scrubbing.py: Test_UrlField: '*': v1.7.1 - fastapi: v2.4.0.dev1 - Test_UrlQuery: v1.6.0rc1.dev + fastapi: v2.4.0 + Test_UrlQuery: v1.6.0-rc1 test_semantic_conventions.py: Test_Meta: v1.80.0 - Test_MetaDatadogTags: bug (Inconsistent implementation across tracers; will need a dedicated testing scenario) + Test_MetaDatadogTags: bug (APMAPI-735) + test_span_events.py: incomplete_test_app (Weblog `/add_event` not implemented) test_standard_tags.py: - Test_StandardTagsClientIp: v2.7.0.dev + Test_StandardTagsClientIp: v2.7.0 Test_StandardTagsMethod: v1.2.1 Test_StandardTagsRoute: v1.6.0 - Test_StandardTagsStatusCode: v1.4.0rc1.dev + Test_StandardTagsStatusCode: v1.4.0-rc1 Test_StandardTagsUrl: - '*': v2.4.0.dev - Test_StandardTagsUserAgent: v1.5.0rc1.dev + '*': v2.4.0 + Test_StandardTagsUserAgent: v1.5.0-rc1 test_telemetry.py: - Test_DependencyEnable: v2.8.0.dev + Test_DependencyEnable: v2.8.0 Test_Log_Generation: missing_feature Test_MessageBatch: missing_feature Test_Metric_Generation_Disabled: missing_feature diff --git a/manifests/ruby.yml b/manifests/ruby.yml index 5717dd31412..72e648c63c4 100644 --- a/manifests/ruby.yml +++ b/manifests/ruby.yml @@ -9,9 +9,8 @@ tests/: test_api_security_rc.py: Test_API_Security_RC_ASM_DD_processors: missing_feature Test_API_Security_RC_ASM_DD_scanners: missing_feature - Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: missing_feature # waf does not support it yet - test_apisec_sampling.py: - Test_API_Security_sampling: missing_feature + Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: irrelevant (waf does not support it yet) + test_apisec_sampling.py: missing_feature test_schemas.py: Test_Scanners: missing_feature Test_Schema_Request_Cookies: v1.15.0 @@ -27,56 +26,97 @@ tests/: Test_Schema_Response_Headers: v1.15.0 iast/: sink/: + test_code_injection.py: + TestCodeInjection: missing_feature + TestCodeInjection_StackTrace: missing_feature test_command_injection.py: TestCommandInjection: missing_feature + TestCommandInjection_StackTrace: missing_feature test_hardcoded_passwords.py: Test_HardcodedPasswords: missing_feature + Test_HardcodedPasswords_StackTrace: missing_feature test_hardcoded_secrets.py: Test_HardcodedSecrets: missing_feature Test_HardcodedSecretsExtended: missing_feature + Test_HardcodedSecrets_StackTrace: missing_feature test_header_injection.py: TestHeaderInjection: missing_feature + TestHeaderInjectionExclusionAccessControlAllow: missing_feature + TestHeaderInjectionExclusionContentEncoding: missing_feature + TestHeaderInjectionExclusionPragma: missing_feature + TestHeaderInjectionExclusionTransferEncoding: missing_feature + TestHeaderInjection_StackTrace: missing_feature test_hsts_missing_header.py: Test_HstsMissingHeader: missing_feature + Test_HstsMissingHeader_StackTrace: missing_feature test_insecure_auth_protocol.py: Test_InsecureAuthProtocol: missing_feature + Test_InsecureAuthProtocol_StackTrace: missing_feature test_insecure_cookie.py: TestInsecureCookie: missing_feature + TestInsecureCookieNameFilter: missing_feature + TestInsecureCookie_StackTrace: missing_feature test_ldap_injection.py: TestLDAPInjection: missing_feature + TestLDAPInjection_StackTrace: missing_feature test_no_httponly_cookie.py: TestNoHttponlyCookie: missing_feature + TestNoHttponlyCookieNameFilter: missing_feature + TestNoHttponlyCookie_StackTrace: missing_feature test_no_samesite_cookie.py: TestNoSamesiteCookie: missing_feature + TestNoSamesiteCookieNameFilter: missing_feature + TestNoSamesiteCookie_StackTrace: missing_feature test_nosql_mongodb_injection.py: TestNoSqlMongodbInjection: missing_feature + TestNoSqlMongodbInjection_StackTrace: missing_feature test_path_traversal.py: TestPathTraversal: missing_feature + TestPathTraversal_StackTrace: missing_feature test_reflection_injection.py: TestReflectionInjection: missing_feature + TestReflectionInjection_StackTrace: missing_feature test_sql_injection.py: TestSqlInjection: missing_feature + TestSqlInjection_StackTrace: missing_feature test_ssrf.py: TestSSRF: missing_feature + TestSSRF_StackTrace: missing_feature + test_template_injection.py: + TestTemplateInjection: missing_feature test_trust_boundary_violation.py: Test_TrustBoundaryViolation: missing_feature + Test_TrustBoundaryViolation_StackTrace: missing_feature + test_untrusted_deserialization.py: + TestUntrustedDeserialization: missing_feature + TestUntrustedDeserialization_StackTrace: missing_feature test_unvalidated_redirect.py: TestUnvalidatedHeader: missing_feature + TestUnvalidatedHeader_StackTrace: missing_feature TestUnvalidatedRedirect: missing_feature + TestUnvalidatedRedirect_StackTrace: missing_feature test_unvalidated_redirect_forward.py: TestUnvalidatedForward: missing_feature + TestUnvalidatedForward_StackTrace: missing_feature test_weak_cipher.py: TestWeakCipher: missing_feature + TestWeakCipher_StackTrace: missing_feature test_weak_hash.py: + TestDeduplication: missing_feature TestWeakHash: missing_feature + TestWeakHash_StackTrace: missing_feature test_weak_randomness.py: TestWeakRandomness: missing_feature + TestWeakRandomness_StackTrace: missing_feature test_xcontent_sniffing.py: Test_XContentSniffing: missing_feature + Test_XContentSniffing_StackTrace: missing_feature test_xpath_injection.py: TestXPathInjection: missing_feature + TestXPathInjection_StackTrace: missing_feature test_xss.py: TestXSS: missing_feature + TestXSS_StackTrace: missing_feature source/: test_body.py: TestRequestBody: missing_feature @@ -102,26 +142,27 @@ tests/: TestParameterValue: missing_feature test_path.py: TestPath: missing_feature + test_path_parameter.py: + TestPathParameter: missing_feature + test_sql_row.py: + TestSqlRow: missing_feature test_uri.py: TestURI: missing_feature rasp/: + test_cmdi.py: missing_feature test_lfi.py: missing_feature - test_span_tags.py: missing_feature + test_shi.py: missing_feature test_sqli.py: missing_feature test_ssrf.py: missing_feature - test_stack_traces.py: missing_feature waf/: test_addresses.py: Test_BodyJson: v1.8.0 Test_BodyRaw: v1.1.0 Test_BodyUrlEncoded: v1.8.0 Test_BodyXml: irrelevant (unsupported by framework) - Test_ClientIP: missing_feature Test_FullGrpc: missing_feature - Test_GraphQL: missing_feature + Test_GraphQL: v2.3.0 Test_GrpcServerMethod: missing_feature - Test_Lambda: missing_feature - Test_Method: missing_feature Test_PathParams: '*': v1.8.0 rack: irrelevant @@ -131,8 +172,8 @@ tests/: Test_gRPC: missing_feature test_blocking.py: Test_Blocking: v1.11.0 - Test_Blocking_strip_response_headers: missing_feature - Test_CustomBlockingResponse: missing_feature + Test_Blocking_strip_response_headers: v1.13.0 + Test_CustomBlockingResponse: v1.15.0 test_custom_rules.py: Test_CustomRules: v1.12.0 test_exclusions.py: @@ -146,15 +187,14 @@ tests/: Test_NoSqli: v1.8.0 test_telemetry.py: Test_TelemetryMetrics: missing_feature - test_PII.py: - Test_Scrubbing: missing_feature test_asm_standalone.py: - Test_AppSecStandalone_UpstreamPropagation: missing_feature + Test_AppSecStandalone_UpstreamPropagation: v2.4.1-dev + Test_IastStandalone_UpstreamPropagation: missing_feature + Test_SCAStandalone_Telemetry: missing_feature test_automated_login_events.py: Test_Login_Events: '*': v1.13.0 rack: missing_feature (We do not support authentication framework for sinatra or rack) - rails32: missing_feature (Not able to configure weblog variant properly. Issue with SQLite and PRIMARY_KEY as String and Rails 3 protected attributes) sinatra14: missing_feature (We do not support authentication framework for sinatra or rack) sinatra20: missing_feature (We do not support authentication framework for sinatra or rack) sinatra21: missing_feature (We do not support authentication framework for sinatra or rack) @@ -167,9 +207,6 @@ tests/: Test_Login_Events_Extended: '*': v1.14.0 rack: missing_feature (We do not support authentication framework for sinatra or rack) - rails32: missing_feature (Not able to configure weblog variant properly. Issue with SQLite and PRIMARY_KEY as String) - rails40: missing_feature (Not able to configure weblog variant properly. Issue with SQLite and PRIMARY_KEY as String) - rails41: missing_feature (Not able to configure weblog variant properly. Issue with SQLite and PRIMARY_KEY as String) sinatra14: missing_feature (We do not support authentication framework for sinatra or rack) sinatra20: missing_feature (We do not support authentication framework for sinatra or rack) sinatra21: missing_feature (We do not support authentication framework for sinatra or rack) @@ -182,10 +219,20 @@ tests/: Test_V2_Login_Events: missing_feature Test_V2_Login_Events_Anon: missing_feature Test_V2_Login_Events_RC: missing_feature + Test_V3_Auto_User_Instrum_Mode_Capability: missing_feature + Test_V3_Login_Events: missing_feature + Test_V3_Login_Events_Anon: missing_feature + Test_V3_Login_Events_Blocking: missing_feature + Test_V3_Login_Events_RC: missing_feature + test_automated_user_and_session_tracking.py: + Test_Automated_Session_Blocking: missing_feature + Test_Automated_User_Blocking: missing_feature + Test_Automated_User_Tracking: missing_feature test_blocking_addresses.py: - Test_BlockingAddresses: v1.0.0 - Test_BlockingGraphqlResolvers: missing_feature + Test_BlockingGraphqlResolvers: v2.3.1-dev + Test_Blocking_client_ip: v1.0.0 Test_Blocking_request_body: v1.0.0 + Test_Blocking_request_body_multipart: v1.0.0 Test_Blocking_request_cookies: v1.0.0 Test_Blocking_request_headers: v1.0.0 Test_Blocking_request_method: v1.12.0 @@ -196,12 +243,10 @@ tests/: Test_Blocking_request_uri: v1.0.0 Test_Blocking_response_headers: v1.0.0 Test_Blocking_response_status: v1.10.0 - Test_Suspicious_Request_Blocking: missing_feature (v1.0.0 but test is not implemented) + Test_Blocking_user_id: v1.0.0 + Test_Suspicious_Request_Blocking: v1.0.0 test_client_ip.py: Test_StandardTagsClientIp: v1.8.0 - test_conf.py: - Test_RuleSet_1_3_1: v1.0.0 - Test_StaticRuleSet: v1.8.0 test_customconf.py: Test_ConfRuleSet: v1.0.0.beta2 Test_CorruptedRules: v1.0.0.beta2 @@ -211,6 +256,14 @@ tests/: Test_CustomEvent: v1.9.0 Test_UserLoginFailureEvent: v1.9.0 Test_UserLoginSuccessEvent: v1.9.0 + test_fingerprinting.py: + Test_Fingerprinting_Endpoint: missing_feature + Test_Fingerprinting_Endpoint_Capability: missing_feature + Test_Fingerprinting_Header_And_Network: missing_feature + Test_Fingerprinting_Header_Capability: missing_feature + Test_Fingerprinting_Network_Capability: missing_feature + Test_Fingerprinting_Session: missing_feature + Test_Fingerprinting_Session_Capability: missing_feature test_identify.py: Test_Basic: v1.0.0 test_ip_blocking_full_denylist.py: @@ -218,20 +271,30 @@ tests/: test_logs.py: Test_Standardization: missing_feature Test_StandardizationBlockMode: missing_feature + test_metastruct.py: + Test_SecurityEvents_Appsec_Metastruct_Disabled: irrelevant (no fallback will be implemented) + Test_SecurityEvents_Appsec_Metastruct_Enabled: missing_feature + Test_SecurityEvents_Iast_Metastruct_Disabled: irrelevant (no fallback will be implemented) + Test_SecurityEvents_Iast_Metastruct_Enabled: missing_feature + test_remote_config_rule_changes.py: + Test_BlockingActionChangesWithRemoteConfig: missing_feature + Test_UpdateRuleFileWithRemoteConfig: missing_feature test_reports.py: - Test_ExtraTagsFromRule: missing_feature + Test_ExtraTagsFromRule: v1.15.0 test_request_blocking.py: Test_AppSecRequestBlocking: v1.11.1 test_runtime_activation.py: Test_RuntimeActivation: missing_feature + Test_RuntimeDeactivation: missing_feature test_shell_execution.py: Test_ShellExecution: missing_feature + test_suspicious_attacker_blocking.py: + Test_Suspicious_Attacker_Blocking: missing_feature test_traces.py: Test_AppSecEventSpanTags: v0.54.2 Test_AppSecObfuscator: v1.0.0 Test_CollectDefaultRequestHeader: missing_feature Test_CollectRespondHeaders: v1.0.0.beta1 - Test_DistributedTraceInfo: missing_feature (test not implemented) Test_ExternalWafRequestsIdentification: v1.22.0 Test_RetainTraces: v0.54.2 test_user_blocking_full_denylist.py: @@ -239,21 +302,28 @@ tests/: test_versions.py: Test_Events: v0.54.2 debugger/: - test_debugger.py: - Test_Debugger_Line_Probe_Snaphots: missing_feature (feature not implented) - Test_Debugger_Method_Probe_Snaphots: missing_feature (feature not implented) - Test_Debugger_Mix_Log_Probe: missing_feature (feature not implented) - Test_Debugger_Probe_Statuses: missing_feature (feature not implented) + test_debugger_exception_replay.py: + Test_Debugger_Exception_Replay: missing_feature (feature not implemented) test_debugger_expression_language.py: - Test_Debugger_Expression_Language: missing_feature (feature not implented) + Test_Debugger_Expression_Language: missing_feature (feature not implemented) test_debugger_pii.py: - Test_Debugger_PII_Redaction: missing_feature (feature not implented) + Test_Debugger_PII_Redaction: + "*": irrelevant + rails70: v2.8.0 + test_debugger_probe_snapshot.py: + Test_Debugger_Probe_Snaphots: + "*": irrelevant + rails70: v2.8.0 + test_debugger_probe_status.py: + Test_Debugger_Probe_Statuses: + "*": irrelevant + rails70: v2.8.0 integrations/: crossed_integrations/: test_kafka.py: Test_Kafka: "*": irrelevant - rails70: v0.1 # real version unknown + rails70: missing_feature (ruby-kafka does not set the kafka topic on spans) test_kinesis.py: Test_Kinesis_PROPAGATION_VIA_MESSAGE_ATTRIBUTES: "*": irrelevant @@ -283,7 +353,7 @@ tests/: Test_DsmContext_Extraction_Base64: "*": irrelevant rails70: missing_feature (Endpoint not implemented) - Test_DsmContext_Injection_Base64: + Test_DsmContext_Injection_Base64: "*": irrelevant rails70: missing_feature (Endpoint not implemented) Test_DsmHttp: missing_feature @@ -308,31 +378,65 @@ tests/: Test_DsmSQS: "*": irrelevant rails70: missing_feature (Endpoint not implemented) + Test_Dsm_Manual_Checkpoint_Inter_Process: + '*': irrelevant + rails70: missing_feature (Endpoint not implemented) + Test_Dsm_Manual_Checkpoint_Intra_Process: + '*': irrelevant + rails70: missing_feature (Endpoint not implemented) + test_inferred_proxy.py: + Test_AWS_API_Gateway_Inferred_Span_Creation: missing_feature + test_otel_drop_in.py: + Test_Otel_Drop_In: missing_feature + k8s_lib_injection/: + test_k8s_lib_injection_profiling.py: + TestK8sLibInjectioProfilingClusterEnabled: missing_feature + TestK8sLibInjectioProfilingClusterOverride: missing_feature + TestK8sLibInjectioProfilingDisabledByDefault: missing_feature + test_k8s_manual_inject.py: + TestAdmisionControllerProfiling: missing_feature parametric/: + test_config_consistency.py: + Test_Config_Dogstatsd: missing_feature + Test_Config_RateLimit: v2.0.0 + Test_Config_Tags: missing_feature + Test_Config_TraceAgentURL: v2.5.0 + Test_Config_TraceEnabled: v2.0.0 + Test_Config_TraceLogDirectory: missing_feature + Test_Config_UnifiedServiceTagging: v2.5.0 + test_crashtracking.py: + Test_Crashtracking: v2.3.0 test_dynamic_configuration.py: - TestDynamicConfigHeaderTags: v2.0.0 TestDynamicConfigSamplingRules: v2.0.0 TestDynamicConfigTracingEnabled: missing_feature - TestDynamicConfigV1: v1.13.0 + TestDynamicConfigV1: bug (APMAPI-867) # theorical version is v1.13.0 TestDynamicConfigV1_ServiceTargets: missing_feature TestDynamicConfigV2: missing_feature + test_headers_baggage.py: + Test_Headers_Baggage: missing_feature test_otel_api_interoperability.py: missing_feature test_otel_env_vars.py: Test_Otel_Env_Vars: v2.1.0 - test_otel_sdk_interoperability.py: missing_feature test_otel_span_methods.py: Test_Otel_Span_Methods: v1.17.0 - test_otel_span_with_w3c.py: - Test_Otel_Span_With_W3c: v1.17.0 + test_otel_span_with_baggage.py: + Test_Otel_Span_With_Baggage: missing_feature + test_parametric_endpoints.py: + Test_Parametric_DDSpan_Set_Resource: incomplete_test_app (set_resource endpoint is not supported) + Test_Parametric_DDTrace_Baggage: missing_feature (baggage is not supported) + Test_Parametric_DDTrace_Current_Span: incomplete_test_app (current span endpoint is not supported) + Test_Parametric_OtelSpan_Set_Name: bug (APMAPI-778) # set_name endpoint should set the resource name on a span (not the operation name) + Test_Parametric_Otel_Baggage: missing_feature (otel baggage is not supported) + Test_Parametric_Otel_Current_Span: incomplete_test_app (otel current span endpoint is not supported) + test_partial_flushing.py: # Not configurable in a standard way + Test_Partial_Flushing: missing_feature test_sampling_delegation.py: - Test_Decisionless_Extraction: >- - missing_feature - (The "_sampling_priority_v1" numeric tag is missing from the local - root span when the trace was extracted without a sampling decision. - See .) - test_span_links.py: + Test_Decisionless_Extraction: v2.4.0 + test_span_events.py: missing_feature + test_span_links.py: Test_Span_Links: v2.0.0 test_telemetry.py: + Test_Consistent_Configs: missing_feature Test_Defaults: missing_feature Test_Environment: missing_feature Test_TelemetryInstallSignature: missing_feature @@ -342,32 +446,69 @@ tests/: Test_Trace_Sampling_Globs: v2.0.0 Test_Trace_Sampling_Globs_Feb2024_Revision: v2.0.0 Test_Trace_Sampling_Resource: v2.0.0 - Test_Trace_Sampling_Tags: missing_feature - Test_Trace_Sampling_Tags_Feb2024_Revision: missing_feature - Test_Trace_Sampling_With_W3C: missing_feature + Test_Trace_Sampling_Tags: v2.4.0 + Test_Trace_Sampling_Tags_Feb2024_Revision: v2.4.0 + Test_Trace_Sampling_With_W3C: v2.4.0 test_tracer.py: - Test_TracerSCITagging: missing_feature + Test_TracerSCITagging: v1.21.0 test_tracer_flare.py: TestTracerFlareV1: missing_feature remote_config/: test_remote_configuration.py: Test_RemoteConfigurationExtraServices: missing_feature - Test_RemoteConfigurationUpdateSequenceASMDD: missing_feature + Test_RemoteConfigurationUpdateSequenceASMDD: v1.13.0 Test_RemoteConfigurationUpdateSequenceASMDDNoCache: missing_feature - Test_RemoteConfigurationUpdateSequenceFeatures: missing_feature + Test_RemoteConfigurationUpdateSequenceFeatures: v1.13.0 Test_RemoteConfigurationUpdateSequenceFeaturesNoCache: missing_feature - Test_RemoteConfigurationUpdateSequenceLiveDebugging: missing_feature - Test_RemoteConfigurationUpdateSequenceLiveDebuggingNoCache: missing_feature + Test_RemoteConfigurationUpdateSequenceLiveDebugging: v1.13.0 + serverless/: + span_pointers/: + aws/: + test_s3_span_pointers.py: + Test_CopyObject: missing_feature + Test_MultipartUpload: missing_feature + Test_PutObject: missing_feature + stats/: + test_miscs.py: + Test_Miscs: missing_feature + test_stats.py: + Test_Client_Stats: missing_feature + test_config_consistency.py: + Test_Config_ClientIPHeaderEnabled_False: v2.8.0 + Test_Config_ClientIPHeader_Configured: v2.3.0 + Test_Config_ClientIPHeader_Precedence: v2.3.0 + Test_Config_ClientTagQueryString_Configured: missing_feature (does not support redacting query string via envar) + Test_Config_ClientTagQueryString_Empty: missing_feature (removes query string by default) + Test_Config_HttpClientErrorStatuses_Default: missing_feature + Test_Config_HttpClientErrorStatuses_FeatureFlagCustom: missing_feature + Test_Config_HttpServerErrorStatuses_Default: v2.0.0 + Test_Config_HttpServerErrorStatuses_FeatureFlagCustom: missing_feature + Test_Config_IntegrationEnabled_False: + '*': irrelevant (endpoint not implemented) + rails70: v2.0.0 + Test_Config_IntegrationEnabled_True: + '*': irrelevant (endpoint not implemented) + rails70: v2.0.0 + Test_Config_ObfuscationQueryStringRegexp_Configured: missing_feature + Test_Config_ObfuscationQueryStringRegexp_Empty: missing_feature (environment variable is not supported) + Test_Config_UnifiedServiceTagging_CustomService: v2.0.0 + Test_Config_UnifiedServiceTagging_Default: v2.0.0 test_distributed.py: Test_DistributedHttp: missing_feature + Test_Span_Links_Flags_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) + Test_Span_Links_From_Conflicting_Contexts: missing_feature + Test_Span_Links_From_Conflicting_Contexts_Datadog_Precedence: missing_feature + Test_Span_Links_Omit_Tracestate_From_Conflicting_Contexts: missing_feature (implementation specs have not been determined) test_identify.py: Test_Basic: v1.0.0 Test_Propagate: missing_feature Test_Propagate_Legacy: missing_feature + test_ipv6.py: missing_feature (APMAPI-869) test_library_conf.py: Test_HeaderTags: v1.13.0 Test_HeaderTags_Colon_Leading: v1.13.0 - Test_HeaderTags_Colon_Trailing: bug (AIT-8602) + Test_HeaderTags_Colon_Trailing: v1.13.0 + Test_HeaderTags_DynamicConfig: bug (APMAPI-867) # theorical version is v2.0.0 Test_HeaderTags_Long: v1.13.0 Test_HeaderTags_Short: v1.13.0 Test_HeaderTags_Whitespace_Header: v1.13.0 @@ -375,7 +516,7 @@ tests/: Test_HeaderTags_Whitespace_Val_Long: v1.13.0 Test_HeaderTags_Whitespace_Val_Short: v1.13.0 test_profiling.py: - Test_Profile: bug (Not receiving profiles) + Test_Profile: missing_feature (temporary fix, scenario not working on dd-trace-rb CI) test_sampling_rates.py: Test_SamplingDecisions: missing_feature (Endpoint /sample_rate_route not implemented) test_scrubbing.py: @@ -383,7 +524,7 @@ tests/: Test_UrlQuery: v1.0.0 test_semantic_conventions.py: Test_Meta: v1.7.0 - Test_MetaDatadogTags: bug (Inconsistent implementation across tracers; will need a dedicated testing scenario) + Test_MetaDatadogTags: v1.9.0 Test_MetricsStandardTags: v1.7.0 test_standard_tags.py: Test_StandardTagsClientIp: v1.10.1 @@ -397,10 +538,10 @@ tests/: test_telemetry.py: Test_DependencyEnable: v1.4.0 Test_Log_Generation: missing_feature - Test_MessageBatch: missing_feature + Test_MessageBatch: v2.2.0 Test_Metric_Generation_Disabled: v1.4.0 Test_Metric_Generation_Enabled: missing_feature - Test_ProductsDisabled: missing_feature + Test_ProductsDisabled: v1.22.0 Test_Telemetry: v1.4.0 Test_TelemetrySCAEnvVar: missing_feature Test_TelemetryV2: v1.11 diff --git a/pyproject.toml b/pyproject.toml index 1256acc2570..5a5f19856e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,11 +3,7 @@ name = 'system_tests' version = '0.0.1' [tool.setuptools] -packages = ["tests", "utils"] - -[tool.black] -line-length = 120 -exclude = "(venv/|utils/grpc/weblog_pb2_grpc.py|utils/grpc/weblog_pb2.py|parametric/apps|parametric/protos/)" +packages = ["tests", "utils", "manifests"] [tool.pytest.ini_options] addopts = "--json-report --json-report-indent=2 --color=yes --no-header --junitxml=reportJunit.xml -r Xf" @@ -43,48 +39,257 @@ allow_no_feature_nodes = [ "tests/parametric/test_span_links.py", "tests/parametric/test_tracer.py", "tests/perfs/test_performances.py", # exotic scenario, not really used - "tests/test_library_logs.py", # we do not have a real feature to attach - "tests/test_miscs.py", # we do not have a real feature to attach - "tests/test_schemas.py", # Too broad test, can't attach to a feature - "tests/test_smoke.py", # Too broad test, can't attach to a feature "tests/test_the_test/", # Not a real test ] -[tool.pylint] -init-hook='import sys; sys.path.append(".")' -max-line-length = 120 -disable = [ - "missing-module-docstring", - "missing-class-docstring", - "missing-function-docstring", - "fixme", - "raise-missing-from", - "invalid-name", - "import-outside-toplevel", - "logging-fstring-interpolation", - "broad-except", - "too-few-public-methods", - "too-many-arguments", - "too-many-branches,", - "bare-except", - "too-many-instance-attributes", - "too-many-locals", - "too-many-public-methods", - "too-many-nested-blocks", - "too-many-return-statements", - "duplicate-code", - "abstract-method", - "inconsistent-return-statements", # because lot of validator function returns nothing - "unused-argument", # pain, as there are some function that MUST have a prototype. TODO... - "attribute-defined-outside-init", +[tool.mypy] +files = ["utils/parametric", "tests/parametric"] +ignore_missing_imports = true +check_untyped_defs = true +disable_error_code = ["no-redef"] +exclude = 'utils/parametric/_library_client\.py|^(?!utils/parametric|tests/parametric).*$' +follow_imports = "skip" +# enable_error_code = ["ignore-without-code"] + +[tool.ruff] +line-length = 120 +indent-width = 4 +target-version = "py312" + +[tool.ruff.format] +exclude = [ + "venv/", + "utils/grpc/weblog_pb2_grpc.py", + "utils/grpc/weblog_pb2.py", "parametric/apps", + "lib-injection/build/docker/python/dd-lib-python-init-test-protobuf-old/addressbook_pb2.py" +] +quote-style = "double" +indent-style = "space" +# skip-magic-trailing-comma = false +# line-ending = "auto" +# docstring-code-format = false +# docstring-code-line-length = "dynamic" + +[tool.ruff.lint] +exclude = [ + "docs/*", +] +select = ["ALL"] + +ignore = [ + ### TODO : remove those ignores + # missing-type-annotation, the ONE to remove !! + "ANN001", + "ANN002", + "ANN003", + "ANN201", + "ANN202", + "ANN205", + "ANN206", + "BLE001", # Do not catch blind exception: `Exception`, big project to enable this + "C901", # code complexity, TBD + "E722", # bare except, big project to enable this + "PERF401", # TBD, the "good" code can be harder to read + "PLR0911", # too many return, may be replaced by a higher default value + "PLR0912", # Too many branches + "PLR0913", # too many arguments, may be replaced by a higher default value + "PLR0915", # too many statements, may be replaced by a higher default value + "PLR1714", + "PLR2004", + "PTH100", + "PTH102", + "PTH110", + "PTH113", + "PTH116", + "PTH118", + "PTH119", + "PTH120", + "PTH122", + "PTH123", # `open()` should be replaced by `Path.open()` + "RUF012", + "S202", + "SIM102", + "SIM110", # TBD + "TRY003", # this is a full project to enable this + + + ### Ignores that will be kept for the entire project + "ANN204", # missing-return-type-special-method + "COM812", # ruff format recommend ignoring this + "D100", # Missing docstring in public module + "D101", # Missing docstring in public class + "D102", # Missing docstring in public method + "D103", # Missing docstring in public function + "D104", # Missing docstring in public package + "D105", # Missing docstring in magic method + "D107", # Missing docstring in `__init__` + "D202", # blank line after docstring + "D203", # cause a warning + "D205", # PEP 257 : blank line after first docstring line + "D211", # no-blank-line-before-class + "D213", # multi-line-summary-second-line + "D400", # First line should end with a period + "D401", # PEP 257 : blank line after first docstring line + "D406", # we are not using numpy convention for docstrings + "D407", # we are not using reStructuredText for docstrings + "D415", # First line should end with a period + "EM101", # Exception must not use a string literal => painful + "EM102", # Exception must not use an f-string => painful + "ERA001", # Found commented-out code + "FIX001", # Fixme found + "FIX002", # Fixme found + "G004", # allow logging with f-string + "I001", # Import block is un-sorted or un-formatted + "ISC001", # ruff format recommend ignoring this + "PTH207", # allow using glob.glob + "S101", # we allow assert! + "S311", # Standard pseudo-random generators are not suitable for cryptographic purposes -> it's testing + "S324", # testing, it's fine + "S603", # allow untrusted input for subprocess + "S607", # allow relative process call + "TD001", # todo found + "TD002", # todo found + "TD003", # todo found + "TD004", # todo found + "TRY300", # not always obvious + "UP038", # not a big fan + ] -ignore-paths = [ - "utils/parametric/protos/.*" # generated by grpc + +[tool.ruff.lint.per-file-ignores] +"utils/grpc/weblog_pb2_grpc.py" = ["ALL"] +"utils/grpc/weblog_pb2.py" = ["ALL"] +"utils/scripts/*" = [ + "INP001", # this is not a package + "T201" # allow print statements in scripts folder ] -generated-members = [ - "pb\\.(DistributedHTTPHeaders|FlushSpansArgs|FlushTraceStatsArgs|HeaderTuple|InjectHeadersArgs)", - "pb\\.(StartSpanArgs|StopTracerArgs|SpanSetMetaArgs|SpanSetMetricArgs|SpanSetErrorArgs|FinishSpanArgs)", - "pb\\.(Otel.*|ListVal|AttrVal|Attributes)", - "(ok_summary|err_summary)\\.mapping", - "Span\\.__annotations__" +"utils/interfaces/schemas/serve_doc.py" = ["INP001"] # this is not a package +"utils/waf_rules.py" = ["N801"] # generated file +# TODO : remove those ignores +"tests/*" = ["ALL"] +"utils/build/*" = ["ALL"] +"lib-injection/*" = ["ALL"] +"utils/{k8s_lib_injection/*,_context/_scenarios/k8s_lib_injection.py}" = [ + "TRY201", + "TRY002", + "D207", + "SIM115", + "S603", + "DTZ005", + "E501", # line too long + "FBT002", # Boolean default positional argument + "SLF001", + "RET505", + "TRY301", + "B006", + "SIM108", + "RET508", + "B007", + "E712", + "F541", + "TRY400", + "N818", + "UP004", + "PTH109", + "UP032", + "EM103", + "B904", + "PTH108", + "A002", + "E401", + "RUF012", + "G002", + "UP031", + "F541" ] + +"utils/onboarding/*" = [ + "DTZ006", + "DTZ005", + "E501", # line too long + "FBT002", # Boolean default positional argument + "UP017", + "N806", + "FBT001", + "S507", + "PTH102", + "PLR2044", + "N803", + "RET505", +] +"utils/{_context/_scenarios/docker_ssi.py,docker_ssi/docker_ssi_matrix_builder.py,docker_ssi/docker_ssi_matrix_utils.py}" = [ + "PLR2004", + "E501", # line too long + "SIM210", + "RET504", + "RET505", + "SIM108", + "T201", +] +"utils/_context/virtual_machines.py" = [ + "ARG002", # unused method argument + "FBT002", # Boolean default positional argument + "N801", # class naming + "S507", # Paramiko call with policy set to automatically trust the unknown host key +] +"utils/virtual_machine/*" = [ + "A002", + "ANN002", + "ANN201", + "ARG001", + "ARG002", + "C901", + "E712", + "E731", + "E501", # line too long + "FBT002", # Boolean default positional argument + "F541", + "E713", + "EM102", + "PLR0912", + "PLR0915", + "PLR1714", + "PLW1510", + "PTH112", + "PTH113", + "PTH116", + "PTH118", + "PTH119", + "RET503", + "RET504", + "RET508", + "RET505", + "RUF013", + "S506", + "S603", + "SIM102", + "SIM113", + "SIM300", + "SIM401", # code quality, TBD + "UP008", + "UP015", + "UP031", + "UP024", + + "BLE001", + "D207", + "F401", + "F811", + "F841", + "N802", + "N803", + "N806", + "PERF401", + "PLR2004", + "PTH101", + "PTH102", + "PTH109", + "S103", + "S113", + "S311", + "S602", + "SIM103", + "SIM115", + "SLF001", + "TRY002", +] \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index be156c93d97..734a8654299 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,44 +1,50 @@ -click==7.1.2 # TODO move once black is moved +click==7.1.2 # TODO update this requests==2.28.1 pytest==7.1.3 pytest-json-report==1.5.0 +pytest-split==0.9.0 pytest-xdist==3.2.1 -black==19.10b0 # TODO : move to 22.8.0 -pylint==2.17.5 +pluggy==1.0.0 +psutil==6.0.0 python-dateutil==2.8.2 msgpack==1.0.4 watchdog==3.0.0 +mypy==1.0.0 +ruff==0.8.1 -aiohttp==3.8.3 -yarl==1.8.1 +aiohttp==3.9.0 +yarl==1.9.4 jsonschema==4.16.0 rfc3339-validator==0.1.4 semantic-version==2.10.0 -matplotlib +matplotlib # for performance tests docker==6.0.0 -paramiko==3.1.0 +paramiko==3.4.1 scp==0.14.5 -ddapm-test-agent==1.14.0 # for parametric tests +ddapm-test-agent==1.18.0 filelock==3.12.2 # for parametric tests dictdiffer==0.9.0 # for parametric tests +opentelemetry-api==1.27.0 # for parametric tests #On Boarding requirements -pulumi==3.73.0 -pulumi-aws==5.41.0 -pulumi-tls==5.0.0a0 -pulumi-command==0.7.2 -pyyaml==6.0.0 +pulumi==3.116.0 +pulumi-aws==6.38.0 +pulumi-tls==5.0.3 +pulumi-command==0.11.1 +pyyaml==6.0.1 pyyaml-include==1.3 python-vagrant==1.0.0 pexpect==4.9.0 +crossplane==0.5.8 #lib-injection kubernetes kubernetes==29.0.0 retry==0.9.2 +boto3==1.35.12 diff --git a/run.sh b/run.sh index b676ec350d9..b5e5e5ee6bb 100755 --- a/run.sh +++ b/run.sh @@ -117,13 +117,9 @@ function lookup_scenario_group() { ;; esac - python+=( - -c 'import yaml; import sys; group = sys.argv[1]; groups = yaml.safe_load(sys.stdin.read()); [[print(t) for t in s] if isinstance(s, list) else print(s) for s in groups[group]]' - ) - - echo "${python[*]}" 1>&2 + python+=(utils/scripts/get-scenarios-from-group.py) - cat < scenario_groups.yml | "${python[@]}" "${group}" + PYTHONPATH=. "${python[@]}" "${group}" } function upcase() { @@ -143,13 +139,12 @@ function activate_venv() { source venv/bin/activate } -function network_name() { - perl -ne '/_NETWORK_NAME = "(.*)"/ and print "$1\n"' utils/_context/containers.py -} - function ensure_network() { local network_name - network_name="$(network_name)" + + # limited support of docker mode: it can't control test targets, so going for the most common use case + # reminder : this mode is unofficial and not supported (for the exact reason it can't control test targets...) + network_name="system-tests-ipv4" if docker network ls | grep -q "${network_name}"; then : # network exists @@ -188,7 +183,7 @@ function run_scenario() { cmd+=( docker run - --network system-tests_default + --network system-tests-ipv4 --rm -i ) if [ -t 1 ]; then @@ -234,6 +229,7 @@ function run_scenario() { } function main() { + local docker="${DOCKER_MODE:-0}" local verbosity=0 local dry=0 @@ -339,20 +335,33 @@ function main() { activate_venv fi + local python_version + python_version="$(python -V 2>&1 | sed -E 's/Python ([0-9]+)\.([0-9]+).*/\1\2/')" + if [[ "$python_version" -lt "312" ]]; then + echo "⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️⚠️⚠️️️️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️⚠️⚠️️️️⚠️⚠️⚠️️️️⚠️⚠️⚠️️️️⚠️⚠️⚠️️️️⚠️⚠️⚠️️️️⚠️" + echo "DEPRECRATION WARNING: you're using python ${python_version} to run system-tests." + echo "This won't be supported soon. Please install python3.12, then run:" + echo "> rm -rf venv && ./build.sh -i runner" + echo "⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️⚠️⚠️️️️" + fi + # process scenario list local scenarios=() # expand scenario groups # bash 3.x does not support mapfile, dance around with tr and IFS - for i in "${scenario_args[@]}"; do - if [[ "${i}" =~ [A-Z0-9_]+_SCENARIOS$ ]]; then - # bash 3.x does not support mapfile, dance around with tr and IFS - IFS=',' read -r -a group <<< "$(lookup_scenario_group "${i}" "${run_mode}" | tr '\n' ',')" - scenarios+=("${group[@]}") - else - scenarios+=("${i}") - fi - done + # bash 3.x considers ${arr[@}} undefined if empty + if [[ ${#scenario_args[@]} -gt 0 ]]; then + for i in "${scenario_args[@]}"; do + if [[ "${i}" =~ [A-Z0-9_]+_SCENARIOS$ ]]; then + # bash 3.x does not support mapfile, dance around with tr and IFS + IFS=',' read -r -a group <<< "$(lookup_scenario_group "${i}" "${run_mode}" | tr '\n' ',')" + scenarios+=("${group[@]}") + else + scenarios+=("${i}") + fi + done + fi # when no scenario is provided, use a nice default if [[ "${#scenarios[@]}" -lt 1 ]]; then @@ -372,6 +381,11 @@ function main() { scenarios+=(LIBRARY_CONF_CUSTOM_HEADER_TAGS) unset "scenarios[${i}]" ;; + + APPSEC_DISABLED) + scenarios+=(EVERYTHING_DISABLED) + unset "scenarios[${i}]" + ;; esac done @@ -398,13 +412,14 @@ function main() { # evaluate max pytest number of process for K8s_lib_injection for scenario in "${scenarios[@]}"; do - #TODO DELETE WHEN THE SCENARIO IS REMOVED. REPLACED BY K8S_LIBRARY_INJECTION - if [[ "${scenario}" == K8S_LIB_INJECTION_* ]]; then - pytest_numprocesses=$(nproc) - fi if [[ "${scenario}" == K8S_LIBRARY_INJECTION_* ]]; then pytest_numprocesses=$(nproc) fi + if [[ "${scenario}" == *_AUTO_INJECTION ]]; then + pytest_numprocesses=6 + #https://pytest-xdist.readthedocs.io/en/latest/distribution.html + pytest_args+=( '--dist' 'loadgroup' ) + fi done case "${pytest_numprocesses}" in @@ -416,7 +431,6 @@ function main() { esac ## run tests - if [[ "${verbosity}" -gt 0 ]]; then echo "plan:" echo " mode: ${run_mode}" @@ -432,6 +446,25 @@ function main() { fi for scenario in "${scenarios[@]}"; do + #TODO SCENARIO WAS REMOVED, TEMPORARY FIX TILL CI IS FIXED + if [[ "${scenario}" == DEBUGGER_METHOD_PROBES_SNAPSHOT ]]; then + echo "${scenario} was removed, skipping." + continue + fi + if [[ "${scenario}" == DEBUGGER_LINE_PROBES_SNAPSHOT ]]; then + echo "${scenario} was removed, skipping." + continue + fi + if [[ "${scenario}" == DEBUGGER_MIX_LOG_PROBE ]]; then + echo "${scenario} was removed, skipping." + continue + fi + if [[ "${scenario}" == REMOTE_CONFIG_MOCKED_BACKEND_LIVE_DEBUGGING_NOCACHE ]]; then + echo "${scenario} was removed, skipping." + continue + fi + #### + run_scenario "${dry}" "${run_mode}" "${scenario}" "${pytest_args[@]}" done } diff --git a/scenario_groups.yml b/scenario_groups.yml deleted file mode 100644 index 904293251fa..00000000000 --- a/scenario_groups.yml +++ /dev/null @@ -1,78 +0,0 @@ -# Scenarios covering AppSec -APPSEC_SCENARIOS: &appsec_scenarios - - APPSEC_MISSING_RULES - - APPSEC_CORRUPTED_RULES - - APPSEC_CUSTOM_RULES - - APPSEC_BLOCKING - - GRAPHQL_APPSEC - - APPSEC_RULES_MONITORING_WITH_ERRORS - - APPSEC_DISABLED - - APPSEC_LOW_WAF_TIMEOUT - - APPSEC_CUSTOM_OBFUSCATION - - APPSEC_RATE_LIMITER - - APPSEC_WAF_TELEMETRY - - APPSEC_BLOCKING_FULL_DENYLIST - - APPSEC_REQUEST_BLOCKING - - APPSEC_RUNTIME_ACTIVATION - - APPSEC_API_SECURITY - - APPSEC_API_SECURITY_NO_RESPONSE_BODY - - APPSEC_AUTO_EVENTS_EXTENDED - - APPSEC_AUTO_EVENTS_RC - - APPSEC_STANDALONE - -# Scenarios covering Remote Configuration -REMOTE_CONFIG_SCENARIOS: &remote_config_scenarios - - REMOTE_CONFIG_MOCKED_BACKEND_ASM_DD - - REMOTE_CONFIG_MOCKED_BACKEND_ASM_DD_NOCACHE - - REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES - - REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES_NOCACHE - - REMOTE_CONFIG_MOCKED_BACKEND_LIVE_DEBUGGING - - REMOTE_CONFIG_MOCKED_BACKEND_LIVE_DEBUGGING_NOCACHE - -# Scenarios covering Telemetry -TELEMETRY_SCENARIOS: &telemetry_scenarios - - TELEMETRY_APP_STARTED_PRODUCTS_DISABLED - - TELEMETRY_DEPENDENCY_LOADED_TEST_FOR_DEPENDENCY_COLLECTION_DISABLED - - TELEMETRY_LOG_GENERATION_DISABLED - - TELEMETRY_METRIC_GENERATION_DISABLED - - TELEMETRY_METRIC_GENERATION_ENABLED - -# Scenarios to run before a tracer release, basically, all stable scenarios -TRACER_RELEASE_SCENARIOS: - - DEFAULT - - TRACE_PROPAGATION_STYLE_W3C - - PROFILING - - LIBRARY_CONF_CUSTOM_HEADER_TAGS - - INTEGRATIONS - - *appsec_scenarios - - *remote_config_scenarios - - *telemetry_scenarios - -# Scenarios to run on tracers PR. -# Those scenarios are the one that offer the best probability-to-catch-bug/time-to-run ratio -TRACER_ESSENTIAL_SCENARIOS: - - DEFAULT - - APPSEC_BLOCKING - - APPSEC_API_SECURITY_RC - - REMOTE_CONFIG_MOCKED_BACKEND_ASM_FEATURES - - INTEGRATIONS - -# Scenarios that rely on backend (and thus, may be a little bit hard to avoid flakyness) -APM_TRACING_E2E_SCENARIOS: - - APM_TRACING_E2E_SINGLE_SPAN - - APM_TRACING_E2E - - APM_TRACING_E2E_OTEL - -# ? -ONBOARDING_SCENARIOS: - - ONBOARDING_HOST - - ONBOARDING_HOST_CONTAINER - - ONBOARDING_CONTAINER - -DEBUGGER_SCENARIOS: - - DEBUGGER_PROBES_STATUS - - DEBUGGER_METHOD_PROBES_SNAPSHOT - - DEBUGGER_LINE_PROBES_SNAPSHOT - - DEBUGGER_MIX_LOG_PROBE - - DEBUGGER_PII_REDACTION - - DEBUGGER_EXPRESSION_LANGUAGE diff --git a/shell.nix b/shell.nix index 8745f5026ca..950c1c81804 100644 --- a/shell.nix +++ b/shell.nix @@ -1 +1,11 @@ -(builtins.getFlake ("git+file://" + toString ./.)).devShells.${builtins.currentSystem}.default +# flake-compat shim for usage without flakes +(import + ( + let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in + fetchTarball { + url = lock.nodes.flake-compat.locked.url or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } + ) + { src = ./.; } +).shellNix diff --git a/tests/apm_tracing_e2e/test_otel.py b/tests/apm_tracing_e2e/test_otel.py index 0001d16930b..a176a6c825b 100644 --- a/tests/apm_tracing_e2e/test_otel.py +++ b/tests/apm_tracing_e2e/test_otel.py @@ -1,11 +1,10 @@ -from utils import context, weblog, scenarios, interfaces, irrelevant, bug, features +from utils import context, weblog, scenarios, interfaces, irrelevant, bug, features, flaky @features.otel_api @scenarios.apm_tracing_e2e_otel class Test_Otel_Span: - """This is a test that that exercises the full flow of APM Tracing with the use of Datadog OTel API. - """ + """This is a test that that exercises the full flow of APM Tracing with the use of Datadog OTel API.""" def setup_datadog_otel_span(self): self.req = weblog.get( @@ -21,7 +20,8 @@ def setup_datadog_otel_span(self): # - tags necessary to retain the mapping between the system-tests/weblog request id and the traces/spans # - duration of one second # - span kind of SpanKind - Internal - @bug(context.library == "java", reason="Span.kind is not set to internal, have type instead") + @bug(context.library == "java", reason="APMAPI-912") + @flaky(library="golang", reason="APMAPI-178") def test_datadog_otel_span(self): spans = interfaces.agent.get_spans_list(self.req) assert 2 <= len(spans), "Agent did not submit the spans we want!" @@ -49,10 +49,11 @@ def test_datadog_otel_span(self): def setup_distributed_otel_trace(self): self.req = weblog.get( - "/e2e_otel_span/mixed_contrib", {"shouldIndex": 1, "parentName": "root-otel-name.dd-resource"}, + "/e2e_otel_span/mixed_contrib", {"shouldIndex": 1, "parentName": "root-otel-name.dd-resource"} ) @irrelevant(condition=context.library != "golang", reason="Golang specific test with OTel Go contrib package") + @flaky(library="golang", reason="APMAPI-178") def test_distributed_otel_trace(self): spans = interfaces.agent.get_spans_list(self.req) assert 3 <= len(spans), "Agent did not submit the spans we want!" diff --git a/utils/build/docker/ruby/rails32/app/mailers/.gitkeep b/tests/appsec/api_security/__init__.py similarity index 100% rename from utils/build/docker/ruby/rails32/app/mailers/.gitkeep rename to tests/appsec/api_security/__init__.py diff --git a/tests/appsec/api_security/test_api_security_rc.py b/tests/appsec/api_security/test_api_security_rc.py index d62f5111865..fc464a0c053 100644 --- a/tests/appsec/api_security/test_api_security_rc.py +++ b/tests/appsec/api_security/test_api_security_rc.py @@ -3,15 +3,13 @@ # Copyright 2021 Datadog, Inc. from utils import ( - context, interfaces, - missing_feature, rfc, scenarios, weblog, features, ) -from utils.tools import logger +from tests.appsec.api_security.utils import BaseAppsecApiSecurityRcTest def get_schema(request, address): @@ -27,11 +25,11 @@ def get_schema(request, address): @rfc("https://docs.google.com/document/d/1Ig5lna4l57-tJLMnC76noGFJaIHvudfYXdZYKz6gXUo/edit#heading=h.88xvn2cvs9dt") @scenarios.appsec_api_security_rc @features.api_security_configuration -class Test_API_Security_RC_ASM_DD_processors: +class Test_API_Security_RC_ASM_DD_processors(BaseAppsecApiSecurityRcTest): """Test API Security - Remote config ASM_DD - processors""" def setup_request_method(self): - interfaces.library.wait_for_remote_config_request() + self.setup_scenario() self.request = weblog.get("/tag_value/api_rc_processor/200?key=value") def test_request_method(self): @@ -47,11 +45,11 @@ def test_request_method(self): @rfc("https://docs.google.com/document/d/1Ig5lna4l57-tJLMnC76noGFJaIHvudfYXdZYKz6gXUo/edit#heading=h.88xvn2cvs9dt") @scenarios.appsec_api_security_rc @features.api_security_configuration -class Test_API_Security_RC_ASM_DD_scanners: +class Test_API_Security_RC_ASM_DD_scanners(BaseAppsecApiSecurityRcTest): """Test API Security - Remote config ASM_DD - scanners""" def setup_request_method(self): - interfaces.library.wait_for_remote_config_request() + self.setup_scenario() self.request = weblog.post("/tag_value/api_rc_scanner/200", data={"mail": "systemtestmail@datadoghq.com"}) def test_request_method(self): @@ -82,13 +80,13 @@ def test_request_method(self): @rfc("https://docs.google.com/document/d/1Ig5lna4l57-tJLMnC76noGFJaIHvudfYXdZYKz6gXUo/edit#heading=h.88xvn2cvs9dt") @scenarios.appsec_api_security_rc @features.api_security_configuration -class Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner: +class Test_API_Security_RC_ASM_processor_overrides_and_custom_scanner(BaseAppsecApiSecurityRcTest): """Test API Security - Remote config ASM - processor_overrides""" request_number = 0 def setup_request_method(self): - interfaces.library.wait_for_remote_config_request() + self.setup_scenario() self.request = weblog.post("/tag_value/api_rc_processor_overrides/200", data={"testcard": "1234567890"}) def test_request_method(self): diff --git a/tests/appsec/api_security/test_apisec_sampling.py b/tests/appsec/api_security/test_apisec_sampling.py index 365ce76ee18..d67637ed2f6 100644 --- a/tests/appsec/api_security/test_apisec_sampling.py +++ b/tests/appsec/api_security/test_apisec_sampling.py @@ -1,4 +1,5 @@ from utils import ( + bug, context, features, interfaces, @@ -11,6 +12,7 @@ from utils.tools import logger import random import string +import time def get_schema(request, address): @@ -26,7 +28,7 @@ def get_schema(request, address): @rfc("https://docs.google.com/document/d/1OCHPBCAErOL2FhLl64YAHB8woDyq66y5t-JGolxdf1Q/edit#heading=h.bth088vsbjrz") @scenarios.appsec_api_security_with_sampling @features.api_security_configuration -class Test_API_Security_sampling: +class Test_API_Security_Sampling_Rate: """Test API Security - Default 0.1 Sampling on Request Headers Schema""" N = 20 # square root of number of requests @@ -36,11 +38,11 @@ def setup_sampling_rate(self): weblog.get( f"/tag_value/api_match_AS001/200?{''.join(random.choices(string.ascii_letters, k=16))}={random.randint(1<<31, (1<<32)-1)}" ) - for _ in range(self.N ** 2) + for _ in range(self.N**2) ] @irrelevant( - context.library not in ["nodejs"], reason="RFC is deprecated by a newer RFC. New tests will be implemented" + context.library not in ("nodejs", "python"), reason="New sampling algorithm tests have been implemented" ) def test_sampling_rate(self): """can provide request header schema""" @@ -56,3 +58,104 @@ def test_sampling_rate(self): ) logger.info(f"API SECURITY SAMPLING RESULT: diff is {diff:.2f} standard deviations") assert diff <= 4.0, "sampling rate is not 0.1" + + +@rfc("https://docs.google.com/document/d/1PYoHms9PPXR8V_5_T5-KXAhoFDKQYA8mTnmS12xkGOE") +@scenarios.appsec_api_security_with_sampling +@features.api_security_configuration +class Test_API_Security_Sampling_Different_Endpoints: + """Test API Security - with different endpoints""" + + def setup_sampling_delay(self): + self.request1 = weblog.get("/api_security/sampling/200") + self.request2 = weblog.get("/api_security_sampling/1") + self.all_requests = [weblog.get("/api_security/sampling/200") for _ in range(10)] + + def test_sampling_delay(self): + assert self.request1.status_code == 200 + schema1 = get_schema(self.request1, "req.headers") + assert schema1 is not None + + assert self.request2.status_code == 200 + schema2 = get_schema(self.request2, "req.headers") + assert schema2 is not None + + assert all(r.status_code == 200 for r in self.all_requests) + assert all(get_schema(r, "req.headers") is None for r in self.all_requests) + + +@rfc("https://docs.google.com/document/d/1PYoHms9PPXR8V_5_T5-KXAhoFDKQYA8mTnmS12xkGOE") +@scenarios.appsec_api_security_with_sampling +@features.api_security_configuration +class Test_API_Security_Sampling_Different_Paths: + """Test API Security - same endpoints but different paths""" + + def setup_sampling_delay(self): + # Wait for 10s to avoid other tests calling same endpoints + time.sleep(10) + self.request1 = weblog.get("/api_security_sampling/11") + self.all_requests = [weblog.get(f"/api_security_sampling/{i}") for i in range(10)] + + def test_sampling_delay(self): + assert self.request1.status_code == 200 + schema1 = get_schema(self.request1, "req.headers") + assert schema1 is not None + + assert all(r.status_code == 200 for r in self.all_requests) + assert all(get_schema(r, "req.headers") is None for r in self.all_requests) + + +@rfc("https://docs.google.com/document/d/1PYoHms9PPXR8V_5_T5-KXAhoFDKQYA8mTnmS12xkGOE") +@scenarios.appsec_api_security_with_sampling +@features.api_security_configuration +class Test_API_Security_Sampling_Different_Status: + """Test API Security - Same endpoint and different status""" + + def setup_sampling_delay(self): + self.request1 = weblog.get("/api_security/sampling/200") + self.request2 = weblog.get("/api_security/sampling/201") + self.all_requests = [weblog.get("/api_security/sampling/201") for _ in range(10)] + + def test_sampling_delay(self): + """can provide request header schema""" + + assert self.request1.status_code == 200 + schema1 = get_schema(self.request1, "req.headers") + assert schema1 is not None + + assert self.request2.status_code == 201 + schema2 = get_schema(self.request2, "req.headers") + assert schema2 is not None + + assert all(r.status_code == 201 for r in self.all_requests) + assert all(get_schema(r, "req.headers") is None for r in self.all_requests) + + +@rfc("https://docs.google.com/document/d/1PYoHms9PPXR8V_5_T5-KXAhoFDKQYA8mTnmS12xkGOE") +@scenarios.appsec_api_security_with_sampling +@features.api_security_configuration +class Test_API_Security_Sampling_With_Delay: + """Test API Security - Same endpoint with delay""" + + def setup_sampling_delay(self): + # Wait for 15s to avoid other tests calling same endpoints + time.sleep(15) + self.request1 = weblog.get("/api_security_sampling/30") + self.request2 = weblog.get("/api_security_sampling/30") + time.sleep(4) # Delay is set to 3s via the env var DD_API_SECURITY_SAMPLE_DELAY + self.request3 = weblog.get("/api_security_sampling/30") + + def test_sampling_delay(self): + """can provide request header schema""" + + assert self.request1.status_code == 200 + assert self.request2.status_code == 200 + + schema1 = get_schema(self.request1, "req.headers") + schema2 = get_schema(self.request2, "req.headers") + + assert (schema1 is None) != (schema2 is None), "Expected exactly one request to be sampled" + + assert self.request3.status_code == 200 + schema3 = get_schema(self.request3, "req.headers") + assert schema3 is not None diff --git a/tests/appsec/api_security/test_schemas.py b/tests/appsec/api_security/test_schemas.py index 1abce03530c..6aa79bc694f 100644 --- a/tests/appsec/api_security/test_schemas.py +++ b/tests/appsec/api_security/test_schemas.py @@ -4,7 +4,6 @@ from utils import ( context, - bug, interfaces, missing_feature, rfc, @@ -78,7 +77,7 @@ class Test_Schema_Request_Cookies: def setup_request_method(self): self.request = weblog.get( - "/tag_value/api_match_AS001/200", cookies={"secret": "any_value", "cache": "any_other_value"}, + "/tag_value/api_match_AS001/200", cookies={"secret": "any_value", "cache": "any_other_value"} ) @missing_feature(context.library < "python@1.19.0.dev") @@ -151,7 +150,7 @@ def test_request_method(self): """can provide request request body schema""" schema = get_schema(self.request, "req.body") assert self.request.status_code == 200 - assert contains(schema, [{"main": [[[{"key": [8], "value": [16]}]], {"len": 2}], "nullable": [1]}],) + assert contains(schema, [{"main": [[[{"key": [8], "value": [16]}]], {"len": 2}], "nullable": [1]}]) @rfc("https://docs.google.com/document/d/1OCHPBCAErOL2FhLl64YAHB8woDyq66y5t-JGolxdf1Q/edit#heading=h.bth088vsbjrz") @@ -177,8 +176,8 @@ def test_request_method(self): schema = get_schema(self.request, "req.body") assert self.request.status_code == 200 assert ( - contains(schema, [{"main": [[[{"key": [8], "value": [8]}]], {"len": 2}], "nullable": [8]}],) - or contains(schema, [{"main": [[[{"key": [8], "value": [16]}]], {"len": 2}], "nullable": [1]}],) + contains(schema, [{"main": [[[{"key": [8], "value": [8]}]], {"len": 2}], "nullable": [8]}]) + or contains(schema, [{"main": [[[{"key": [8], "value": [16]}]], {"len": 2}], "nullable": [1]}]) or contains( schema, [ @@ -222,7 +221,7 @@ class Test_Schema_Response_Body: def setup_request_method(self): self.request = weblog.post( "/tag_value/payload_in_response_body_001/200", - data={"test_int": 1, "test_str": "anything", "test_bool": True, "test_float": 1.5234,}, + data={"test_int": 1, "test_str": "anything", "test_bool": True, "test_float": 1.5234}, ) def test_request_method(self): @@ -251,7 +250,7 @@ class Test_Schema_Response_Body_env_var: def setup_request_method(self): self.request = weblog.post( "/tag_value/payload_in_response_body_001/200?X-option=test_value", - data={"test_int": 1, "test_str": "anything", "test_bool": True, "test_float": 1.5234,}, + data={"test_int": 1, "test_str": "anything", "test_bool": True, "test_float": 1.5234}, ) def test_request_method(self): @@ -277,8 +276,8 @@ class Test_Scanners: def setup_request_method(self): self.request = weblog.get( "/tag_value/api_match_AS001/200", - cookies={"mastercard": "5123456789123456", "authorization": "digest_a0b1c2", "SSN": "123-45-6789",}, - headers={"authorization": "digest a0b1c2",}, + cookies={"mastercard": "5123456789123456", "authorization": "digest_a0b1c2", "SSN": "123-45-6789"}, + headers={"authorization": "digest a0b1c2"}, ) @missing_feature(context.library < "python@1.19.0.dev") @@ -295,7 +294,7 @@ def test_request_method(self): { "SSN": [8, {"category": "pii", "type": "us_ssn"}], "authorization": [8], - "mastercard": [8, {"card_type": "mastercard", "type": "card", "category": "payment"},], + "mastercard": [8, {"card_type": "mastercard", "type": "card", "category": "payment"}], }, { "SSN": [[[8, {"category": "pii", "type": "us_ssn"}]], {"len": 1}], @@ -312,7 +311,6 @@ def test_request_method(self): (schema_cookies[0], EXPECTED_COOKIES), (schema_headers[0], EXPECTED_HEADERS), ]: - for key in expected[0]: assert key in schema assert isinstance(schema[key], list) diff --git a/tests/appsec/api_security/utils.py b/tests/appsec/api_security/utils.py new file mode 100644 index 00000000000..fdc7db27204 --- /dev/null +++ b/tests/appsec/api_security/utils.py @@ -0,0 +1,127 @@ +from utils import remote_config + + +class BaseAppsecApiSecurityRcTest: + states = None + + def setup_scenario(self): + if BaseAppsecApiSecurityRcTest.states is None: + rc_state = remote_config.rc_state + rc_state.set_config( + "datadog/2/ASM/ASM-base/config", + { + "processor_override": [ + {"target": ["extract-content"], "scanners": ["test-scanner-002", "test-scanner-custom-001"]} + ], + "custom_scanners": [ + { + "id": "test-scanner-custom-001", + "name": "Custom scanner", + "key": { + "operator": "match_regex", + "parameters": { + "regex": "\\btestcard\\b", + "options": {"case_sensitive": False, "min_length": 2}, + }, + }, + "value": { + "operator": "match_regex", + "parameters": { + "regex": "\\b1234567890\\b", + "options": {"case_sensitive": False, "min_length": 5}, + }, + }, + "tags": {"type": "card", "category": "testcategory"}, + } + ], + }, + ) + rc_state.set_config( + "datadog/2/ASM_DD/ASM_DD-base/config", + { + "version": "2.2", + "metadata": {"rules_version": "1.10.0"}, + "rules": [ + { + "id": "test-001", + "name": "Test 001 rule", + "tags": {"type": "commercial_scanner", "category": "attack_attemp"}, + "conditions": [ + { + "parameters": { + "inputs": [ + {"address": "server.request.query"}, + {"address": "server.request.uri.raw"}, + {"address": "server.request.body"}, + ], + "regex": "testattack", + "options": {"case_sensitive": False}, + }, + "operator": "match_regex", + } + ], + } + ], + "processors": [ + { + "id": "extract-content", + "generator": "extract_schema", + "conditions": [ + { + "operator": "equals", + "parameters": { + "inputs": [ + {"address": "waf.context.processor", "key_path": ["extract-schema"]} + ], + "type": "boolean", + "value": True, + }, + } + ], + "parameters": { + "mappings": [ + { + "inputs": [{"address": "server.request.query"}], + "output": "_dd.appsec.s.req.querytest", + }, + { + "inputs": [{"address": "server.request.body"}], + "output": "_dd.appsec.s.req.bodytest", + }, + ], + "scanners": [{"tags": {"category": "pii"}}], + }, + "evaluate": True, + "output": True, + } + ], + "scanners": [ + { + "id": "test-scanner-001", + "name": "Standard E-mail Address", + "key": { + "operator": "match_regex", + "parameters": { + "regex": "\\b(?:(?:e[-\\s]?)?mail|address|sender|\\bto\\b|from|recipient)\\b", + "options": {"case_sensitive": False, "min_length": 2}, + }, + }, + "value": { + "operator": "match_regex", + "parameters": { + "regex": "\\b[\\w!#$%&'*+/=?`{|}~^-]+(?:\\.[\\w!#$%&'*+/=?`{|}~^-]+)*" + "(%40|@)(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}\\b", + "options": {"case_sensitive": False, "min_length": 5}, + }, + }, + "tags": {"type": "email", "category": "pii"}, + } + ], + }, + ) + rc_state.set_config( + "datadog/2/ASM_FEATURES/ASM_FEATURES-base/config", + {"asm": {"enabled": True}, "api_security": {"request_sample_rate": 1.0}}, + ) + + BaseAppsecApiSecurityRcTest.states = rc_state.apply() diff --git a/tests/appsec/appsec_corrupted_rules.json b/tests/appsec/appsec_corrupted_rules.json new file mode 100644 index 00000000000..24c1f5b0934 --- /dev/null +++ b/tests/appsec/appsec_corrupted_rules.json @@ -0,0 +1 @@ +corrupted::data diff --git a/tests/appsec/blocking_rule.json b/tests/appsec/blocking_rule.json index 52397122218..5f2e03dc9be 100644 --- a/tests/appsec/blocking_rule.json +++ b/tests/appsec/blocking_rule.json @@ -208,7 +208,7 @@ ] } ], - "regex": "en-us|krypton" + "regex": "fo-fo|krypton" }, "operator": "match_regex", "options": { @@ -494,6 +494,157 @@ "block" ] }, + { + "id": "tst-037-012", + "name": "Test block on multiple request addresses", + "tags": { + "type": "lfi", + "crs_id": "000012", + "category": "attack_attempt" + }, + "conditions": [ + { + "parameters": { + "inputs": [ + { + "address": "server.request.method" + } + ], + "regex": "GET" + }, + "operator": "match_regex" + }, + { + "parameters": { + "inputs": [ + { + "address": "server.request.uri.raw" + } + ], + "regex": "malicious-uri-ypMrmzrWATkLrPKLblvpRGGltBSgHWrK" + }, + "operator": "match_regex" + }, + { + "parameters": { + "inputs": [ + { + "address": "server.request.path_params" + } + ], + "regex": "malicious-path-cGDgSRJvklxGOKMTNfQMViBPpKAvpFoc" + }, + "operator": "match_regex" + }, + { + "parameters": { + "inputs": [ + { + "address": "server.request.query" + } + ], + "regex": "malicious-query-SAGihOkuSwXXFDXNqAWJzNuZEdKNunrJ" + }, + "operator": "match_regex" + }, + { + "parameters": { + "inputs": [ + { + "address": "server.request.headers.no_cookies" + } + ], + "regex": "malicious-header-kCgvxrYeiwUSYkAuniuGktdvzXYEPSff" + }, + "operator": "match_regex" + }, + { + "parameters": { + "inputs": [ + { + "address": "server.request.cookies" + } + ], + "regex": "malicious-cookie-PwXuEQEdeAjzWpCDqAzPqiUAdXJMHwtS" + }, + "operator": "match_regex" + } + ], + "transformers": [], + "on_match": [ + "block" + ] + }, + { + "id": "tst-037-013", + "name": "Test block on multiple request addresses (without path_params)", + "tags": { + "type": "lfi", + "crs_id": "000013", + "category": "attack_attempt" + }, + "conditions": [ + { + "parameters": { + "inputs": [ + { + "address": "server.request.method" + } + ], + "regex": "GET" + }, + "operator": "match_regex" + }, + { + "parameters": { + "inputs": [ + { + "address": "server.request.uri.raw" + } + ], + "regex": "malicious-uri-wX1GdUiWdVdoklf0pYBi5kQApO9i77tN" + }, + "operator": "match_regex" + }, + { + "parameters": { + "inputs": [ + { + "address": "server.request.query" + } + ], + "regex": "malicious-query-T3d1nKdkTWIG03q03ix9c9UlhbGigvwQ" + }, + "operator": "match_regex" + }, + { + "parameters": { + "inputs": [ + { + "address": "server.request.headers.no_cookies" + } + ], + "regex": "malicious-header-siDzyETAdkvKahD3PxlvIqcE0fMIVywE" + }, + "operator": "match_regex" + }, + { + "parameters": { + "inputs": [ + { + "address": "server.request.cookies" + } + ], + "regex": "malicious-cookie-qU4sV2r6ac2nfETV7aJP9Fdt1NaWC9wB" + }, + "operator": "match_regex" + } + ], + "transformers": [], + "on_match": [ + "block" + ] + }, { "id": "monitor-resolvers", "name": "Monitor Resolvers", diff --git a/tests/appsec/iast/sink/test_code_injection.py b/tests/appsec/iast/sink/test_code_injection.py new file mode 100644 index 00000000000..2a9e0ee534b --- /dev/null +++ b/tests/appsec/iast/sink/test_code_injection.py @@ -0,0 +1,38 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2021 Datadog, Inc. + +from utils import context, missing_feature, features, rfc, weblog +from ..utils import BaseSinkTest, validate_stack_traces + + +@features.iast_sink_code_injection +class TestCodeInjection(BaseSinkTest): + """Test command injection detection.""" + + vulnerability_type = "CODE_INJECTION" + http_method = "POST" + insecure_endpoint = "/iast/code_injection/test_insecure" + secure_endpoint = "/iast/code_injection/test_secure" + data = {"code": "1+2"} + location_map = { + "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"}, + } + + @missing_feature(library="nodejs", reason="Instrumented metric not implemented") + def test_telemetry_metric_instrumented_sink(self): + super().test_telemetry_metric_instrumented_sink() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestCodeInjection_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post("/iast/code_injection/test_insecure", data={"code": "1+2"}) + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_command_injection.py b/tests/appsec/iast/sink/test_command_injection.py index b3301f9fc17..317367cb28a 100644 --- a/tests/appsec/iast/sink/test_command_injection.py +++ b/tests/appsec/iast/sink/test_command_injection.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, missing_feature, features -from ..utils import BaseSinkTest +from utils import context, missing_feature, features, rfc, weblog +from ..utils import BaseSinkTest, validate_stack_traces @features.iast_sink_command_injection @@ -17,7 +17,7 @@ class TestCommandInjection(BaseSinkTest): data = {"cmd": "ls"} location_map = { "java": "com.datadoghq.system_tests.iast.utils.CmdExamples", - "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}, + "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"}, "python": {"flask-poc": "app.py", "django-poc": "app/urls.py"}, } @@ -34,3 +34,17 @@ def test_telemetry_metric_instrumented_sink(self): @missing_feature(context.library < "java@1.9.0", reason="Metrics not implemented") def test_telemetry_metric_executed_sink(self): super().test_telemetry_metric_executed_sink() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestCommandInjection_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post("/iast/cmdi/test_insecure", data={"cmd": "ls"}) + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_hardcoded_passwords.py b/tests/appsec/iast/sink/test_hardcoded_passwords.py index 0d4581e5ff4..6f6c58359dd 100644 --- a/tests/appsec/iast/sink/test_hardcoded_passwords.py +++ b/tests/appsec/iast/sink/test_hardcoded_passwords.py @@ -2,7 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import interfaces, weblog, features, context, missing_feature +from utils import interfaces, weblog, features, context, rfc +from ..utils import validate_stack_traces # Test_HardcodedPasswords doesn't inherit from BaseSinkTest # Hardcode passwords detection implementation change a lot between different languages @@ -15,11 +16,19 @@ class Test_HardcodedPasswords: """Test Hardcoded passwords detection.""" location_map = { - "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "uds-express4": "iast/index.js"}, + "nodejs": { + "express4": "iast/index.js", + "express4-typescript": "iast.ts", + "express5": "iast/index.js", + "uds-express4": "iast/index.js", + }, } + insecure_request = None + def setup_hardcoded_passwords_exec(self): self.r_hardcoded_passwords_exec = weblog.get("/iast/hardcoded_passwords/test_insecure") + self.__class__.insecure_request = self.r_hardcoded_passwords_exec def test_hardcoded_passwords_exec(self): assert self.r_hardcoded_passwords_exec.status_code == 200 @@ -48,3 +57,17 @@ def _get_expectation(self, d): if isinstance(expected, dict): expected = expected.get(context.weblog_variant) return expected + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class Test_HardcodedPasswords_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.get("/iast/hardcoded_passwords/test_insecure") + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_hardcoded_secrets.py b/tests/appsec/iast/sink/test_hardcoded_secrets.py index a5600632867..28eda35e9f6 100644 --- a/tests/appsec/iast/sink/test_hardcoded_secrets.py +++ b/tests/appsec/iast/sink/test_hardcoded_secrets.py @@ -2,7 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import interfaces, weblog, features, context, missing_feature +from utils import interfaces, weblog, features, context, rfc, weblog +from ..utils import validate_stack_traces # Test_HardcodedSecrets and Test_HardcodedSecretsExtended don't inherit from BaseSinkTest # Hardcode secrets detection implementation change a lot between different languages @@ -38,11 +39,19 @@ class Test_HardcodedSecrets: location_map = { "java": "com.datadoghq.system_tests.springboot.AppSecIast", - "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "uds-express4": "iast/index.js"}, + "nodejs": { + "express4": "iast/index.js", + "express4-typescript": "iast.ts", + "express5": "iast/index.js", + "uds-express4": "iast/index.js", + }, } + insecure_request = None + def setup_hardcoded_secrets_exec(self): self.r_hardcoded_secrets_exec = weblog.get("/iast/hardcoded_secrets/test_insecure") + self.__class__.insecure_request = self.r_hardcoded_secrets_exec def test_hardcoded_secrets_exec(self): assert self.r_hardcoded_secrets_exec.status_code == 200 @@ -58,7 +67,12 @@ class Test_HardcodedSecretsExtended: """Test Hardcoded secrets extended detection.""" location_map = { - "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "uds-express4": "iast/index.js"}, + "nodejs": { + "express4": "iast/index.js", + "express4-typescript": "iast.ts", + "express5": "iast/index.js", + "uds-express4": "iast/index.js", + }, } def setup_hardcoded_secrets_extended_exec(self): @@ -71,3 +85,17 @@ def test_hardcoded_secrets_extended_exec(self): assert len(hardcoded_secrets) == 1 vuln = hardcoded_secrets[0] assert vuln["location"]["path"] == get_expectation(self.location_map) + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class Test_HardcodedSecrets_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.get("/iast/hardcoded_secrets/test_insecure") + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_header_injection.py b/tests/appsec/iast/sink/test_header_injection.py index 242f7587616..0804d74fd18 100644 --- a/tests/appsec/iast/sink/test_header_injection.py +++ b/tests/appsec/iast/sink/test_header_injection.py @@ -2,8 +2,48 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, features, missing_feature -from ..utils import BaseSinkTest +from utils import context, features, missing_feature, rfc, weblog +from ..utils import BaseSinkTest, validate_stack_traces, assert_iast_vulnerability + + +class _BaseTestHeaderInjectionReflectedExclusion: + origin_header: None + reflected_header: None + headers: None + + exclusion_request: None + no_exclusion_request: None + + def setup_no_exclusion(self): + assert self.origin_header is not None, f"Please set {self}.origin_header" + assert isinstance(self.origin_header, str), f"Please set {self}.origin_header" + assert self.reflected_header is not None, f"Please set {self}.reflected_header" + assert isinstance(self.reflected_header, str), f"Please set {self}.reflected_header" + + self.no_exclusion_request = weblog.get( + path="/iast/header_injection/reflected/no-exclusion", + params={"origin": self.origin_header, "reflected": self.reflected_header}, + ) + + def test_no_exclusion(self): + assert_iast_vulnerability( + request=self.no_exclusion_request, vulnerability_count=1, vulnerability_type="HEADER_INJECTION" + ) + + def setup_exclusion(self): + assert self.origin_header is not None, f"Please set {self}.origin_header" + assert isinstance(self.origin_header, str), f"Please set {self}.origin_header" + assert self.reflected_header is not None, f"Please set {self}.reflected_header" + assert isinstance(self.reflected_header, str), f"Please set {self}.reflected_header" + + self.exclusion_request = weblog.get( + path="/iast/header_injection/reflected/exclusion", + params={"origin": self.origin_header, "reflected": self.reflected_header}, + headers=self.headers, + ) + + def test_exclusion(self): + BaseSinkTest.assert_no_iast_event(self.exclusion_request) @features.iast_sink_header_injection @@ -15,7 +55,9 @@ class TestHeaderInjection(BaseSinkTest): insecure_endpoint = "/iast/header_injection/test_insecure" secure_endpoint = "/iast/header_injection/test_secure" data = {"test": "dummyvalue"} - location_map = {"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}} + location_map = { + "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"} + } @missing_feature(context.library < "java@1.22.0", reason="Metrics not implemented") @missing_feature(library="dotnet", reason="Not implemented yet") @@ -25,3 +67,53 @@ def test_telemetry_metric_instrumented_sink(self): @missing_feature(context.library < "java@1.22.0", reason="Metrics not implemented") def test_telemetry_metric_executed_sink(self): super().test_telemetry_metric_executed_sink() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestHeaderInjection_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post("/iast/header_injection/test_insecure", data={"test": "dummyvalue"}) + + def test_stack_trace(self): + validate_stack_traces(self.r) + + +@features.iast_sink_header_injection +class TestHeaderInjectionExclusionAccessControlAllow(_BaseTestHeaderInjectionReflectedExclusion): + """Verify Header injection Access-Control-Allow-* reflexion exclusion""" + + origin_header = "x-custom-header" + reflected_header = "access-control-allow-origin" + headers = {"x-custom-header": "allowed-origin"} + + +@features.iast_sink_header_injection +class TestHeaderInjectionExclusionContentEncoding(_BaseTestHeaderInjectionReflectedExclusion): + """Verify Header injection Content-Encoding reflexion exclusion""" + + origin_header = "accept-encoding" + reflected_header = "content-encoding" + headers = {"accept-encoding": "foo, bar"} + + +@features.iast_sink_header_injection +class TestHeaderInjectionExclusionPragma(_BaseTestHeaderInjectionReflectedExclusion): + """Verify Header injection Pragma reflexion exclusion""" + + origin_header = "cache-control" + reflected_header = "pragma" + headers = {"cache-control": "cacheControlValue"} + + +@features.iast_sink_header_injection +class TestHeaderInjectionExclusionTransferEncoding(_BaseTestHeaderInjectionReflectedExclusion): + """Verify Header injection Transfer-Encoding reflexion exclusion""" + + origin_header = "accept-encoding" + reflected_header = "transfer-encoding" + headers = {"accept-encoding": "foo, bar"} diff --git a/tests/appsec/iast/sink/test_hsts_missing_header.py b/tests/appsec/iast/sink/test_hsts_missing_header.py index a2aa732847b..1b372e52f52 100644 --- a/tests/appsec/iast/sink/test_hsts_missing_header.py +++ b/tests/appsec/iast/sink/test_hsts_missing_header.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, missing_feature, features -from ..utils import BaseSinkTest +from utils import context, missing_feature, features, rfc, weblog +from ..utils import BaseSinkTest, validate_stack_traces @features.iast_sink_hsts_missing_header @@ -25,3 +25,17 @@ def test_telemetry_metric_instrumented_sink(self): @missing_feature(context.library < "java@1.22.0", reason="Metrics not implemented") def test_telemetry_metric_executed_sink(self): super().test_telemetry_metric_executed_sink() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class Test_HstsMissingHeader_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.get("/iast/hstsmissing/test_insecure", headers={"X-Forwarded-Proto": "https"}) + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_insecure_auth_protocol.py b/tests/appsec/iast/sink/test_insecure_auth_protocol.py index ecb81977de2..754e682b191 100644 --- a/tests/appsec/iast/sink/test_insecure_auth_protocol.py +++ b/tests/appsec/iast/sink/test_insecure_auth_protocol.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, missing_feature, features -from ..utils import BaseSinkTest +from utils import context, missing_feature, features, rfc, weblog +from ..utils import BaseSinkTest, validate_stack_traces @features.iast_sink_insecure_auth_protocol @@ -27,3 +27,23 @@ def test_telemetry_metric_instrumented_sink(self): @missing_feature(library="java", reason="Not implemented yet") def test_telemetry_metric_executed_sink(self): super().test_telemetry_metric_executed_sink() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class Test_InsecureAuthProtocol_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.get( + "/iast/insecure-auth-protocol/test_insecure", + headers={ + "Authorization": 'Digest username="WATERFORD", realm="Users", nonce="c5rcvu346qavqf3hnmsrnqj5up", uri="/api/partner/validate", response="57c8d9f11ec7a2f1ab13c5e166b2c505"' + }, + ) + + @missing_feature(library="java", reason="Not implemented yet") + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_insecure_cookie.py b/tests/appsec/iast/sink/test_insecure_cookie.py index 474710e06c6..ba5aff1d1d2 100644 --- a/tests/appsec/iast/sink/test_insecure_cookie.py +++ b/tests/appsec/iast/sink/test_insecure_cookie.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, missing_feature, bug, weblog, features -from ..utils import BaseSinkTest +from utils import context, missing_feature, bug, weblog, features, rfc, scenarios +from ..utils import BaseSinkTest, BaseTestCookieNameFilter, validate_stack_traces @features.iast_sink_insecure_cookie @@ -15,9 +15,11 @@ class TestInsecureCookie(BaseSinkTest): insecure_endpoint = "/iast/insecure-cookie/test_insecure" secure_endpoint = "/iast/insecure-cookie/test_secure" data = {} - location_map = {"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}} + location_map = { + "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"} + } - @bug(context.library < "java@1.18.3", reason="Incorrect handling of HttpOnly flag") + @bug(context.library < "java@1.18.3", reason="APMRP-360") def test_secure(self): super().test_secure() @@ -37,3 +39,26 @@ def test_telemetry_metric_instrumented_sink(self): @missing_feature(weblog_variant="vertx4", reason="Metrics not implemented") def test_telemetry_metric_executed_sink(self): super().test_telemetry_metric_executed_sink() + + +@features.iast_sink_insecure_cookie +@scenarios.iast_deduplication +class TestInsecureCookieNameFilter(BaseTestCookieNameFilter): + """Test no SameSite cookie name filter.""" + + vulnerability_type = "INSECURE_COOKIE" + endpoint = "/iast/insecure-cookie/custom_cookie" + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestInsecureCookie_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.get("/iast/insecure-cookie/test_insecure") + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_ldap_injection.py b/tests/appsec/iast/sink/test_ldap_injection.py index 6469e2f6a5f..527fac132b4 100644 --- a/tests/appsec/iast/sink/test_ldap_injection.py +++ b/tests/appsec/iast/sink/test_ldap_injection.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, missing_feature, features -from ..utils import BaseSinkTest +from utils import context, missing_feature, features, rfc, weblog +from ..utils import BaseSinkTest, validate_stack_traces @features.iast_sink_ldap_injection @@ -17,7 +17,7 @@ class TestLDAPInjection(BaseSinkTest): data = {"username": "ssam", "password": "sammy"} location_map = { "java": "com.datadoghq.system_tests.iast.utils.LDAPExamples", - "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}, + "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"}, } @missing_feature(context.library < "java@1.9.0", reason="Metrics not implemented") @@ -28,3 +28,17 @@ def test_telemetry_metric_instrumented_sink(self): @missing_feature(context.library < "java@1.11.0", reason="Metrics not implemented") def test_telemetry_metric_executed_sink(self): super().test_telemetry_metric_executed_sink() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestLDAPInjection_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post("/iast/ldapi/test_insecure", data={"username": "ssam", "password": "sammy"}) + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_no_httponly_cookie.py b/tests/appsec/iast/sink/test_no_httponly_cookie.py index 9b8723612af..ceb566b7542 100644 --- a/tests/appsec/iast/sink/test_no_httponly_cookie.py +++ b/tests/appsec/iast/sink/test_no_httponly_cookie.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, missing_feature, bug, weblog, features -from ..utils import BaseSinkTest +from utils import context, missing_feature, bug, weblog, features, rfc, scenarios +from ..utils import BaseSinkTest, BaseTestCookieNameFilter, validate_stack_traces @features.iast_sink_http_only_cookie @@ -15,25 +15,50 @@ class TestNoHttponlyCookie(BaseSinkTest): insecure_endpoint = "/iast/no-httponly-cookie/test_insecure" secure_endpoint = "/iast/no-httponly-cookie/test_secure" data = {} - location_map = {"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}} + location_map = { + "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"} + } - @bug(context.library < "java@1.18.3", reason="Incorrect handling of HttpOnly flag") + @bug(context.library < "java@1.18.3", reason="APMRP-360") def test_secure(self): super().test_secure() def setup_empty_cookie(self): self.request_empty_cookie = weblog.get("/iast/no-httponly-cookie/test_empty_cookie", data={}) - @missing_feature(library="java", reason="Endpoint not implemented") def test_empty_cookie(self): self.assert_no_iast_event(self.request_empty_cookie) - @missing_feature(library="java", reason="Metrics not implemented") + @missing_feature(context.library < "java@1.22.0", reason="Metrics not implemented") @missing_feature(library="python", reason="Metrics not implemented") @missing_feature(library="dotnet", reason="Metrics not implemented") def test_telemetry_metric_instrumented_sink(self): super().test_telemetry_metric_instrumented_sink() - @missing_feature(library="java", reason="Metrics not implemented") + @missing_feature(context.library < "java@1.22.0", reason="Metric not implemented") + @missing_feature(weblog_variant="vertx4", reason="Metric not implemented") def test_telemetry_metric_executed_sink(self): super().test_telemetry_metric_executed_sink() + + +@features.iast_sink_http_only_cookie +@scenarios.iast_deduplication +class TestNoHttponlyCookieNameFilter(BaseTestCookieNameFilter): + """Test no HttpOnly cookie name filter.""" + + vulnerability_type = "NO_HTTPONLY_COOKIE" + endpoint = "/iast/no-httponly-cookie/custom_cookie" + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestNoHttponlyCookie_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.get("/iast/no-httponly-cookie/test_insecure") + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_no_samesite_cookie.py b/tests/appsec/iast/sink/test_no_samesite_cookie.py index 60e4e08e317..3a737f08708 100644 --- a/tests/appsec/iast/sink/test_no_samesite_cookie.py +++ b/tests/appsec/iast/sink/test_no_samesite_cookie.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, missing_feature, bug, weblog, features -from ..utils import BaseSinkTest +from utils import context, missing_feature, bug, weblog, features, rfc, scenarios +from ..utils import BaseSinkTest, BaseTestCookieNameFilter, validate_stack_traces @features.iast_sink_samesite_cookie @@ -15,16 +15,17 @@ class TestNoSamesiteCookie(BaseSinkTest): insecure_endpoint = "/iast/no-samesite-cookie/test_insecure" secure_endpoint = "/iast/no-samesite-cookie/test_secure" data = {} - location_map = {"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}} + location_map = { + "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"} + } - @bug(context.library < "java@1.18.3", reason="Incorrect handling of HttpOnly flag") + @bug(context.library < "java@1.18.3", reason="APMRP-360") def test_secure(self): super().test_secure() def setup_empty_cookie(self): self.request_empty_cookie = weblog.get("/iast/no-samesite-cookie/test_empty_cookie", data={}) - @missing_feature(library="python", reason="Endpoint not implemented") def test_empty_cookie(self): self.assert_no_iast_event(self.request_empty_cookie) @@ -38,3 +39,26 @@ def test_telemetry_metric_instrumented_sink(self): @missing_feature(weblog_variant="vertx4", reason="Metrics not implemented") def test_telemetry_metric_executed_sink(self): super().test_telemetry_metric_executed_sink() + + +@features.iast_sink_samesite_cookie +@scenarios.iast_deduplication +class TestNoSamesiteCookieNameFilter(BaseTestCookieNameFilter): + """Test no SameSite cookie name filter.""" + + vulnerability_type = "NO_SAMESITE_COOKIE" + endpoint = "/iast/no-samesite-cookie/custom_cookie" + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestNoSamesiteCookie_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.get("/iast/no-samesite-cookie/test_insecure") + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_nosql_mongodb_injection.py b/tests/appsec/iast/sink/test_nosql_mongodb_injection.py index 85a6b6ae7c3..b5c157cd634 100644 --- a/tests/appsec/iast/sink/test_nosql_mongodb_injection.py +++ b/tests/appsec/iast/sink/test_nosql_mongodb_injection.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, missing_feature, scenarios, features -from ..utils import BaseSinkTest +from utils import context, missing_feature, scenarios, features, rfc, weblog +from ..utils import BaseSinkTest, validate_stack_traces @scenarios.integrations @@ -16,7 +16,15 @@ class TestNoSqlMongodbInjection(BaseSinkTest): insecure_endpoint = "/iast/mongodb-nosql-injection/test_insecure" secure_endpoint = "/iast/mongodb-nosql-injection/test_secure" data = {"key": "somevalue"} - location_map = {"nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}} + location_map = { + "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"} + } + + @missing_feature( + context.weblog_variant == "express5", reason="express-mongo-sanitize is not yet compatible with express5" + ) + def test_secure(self): + super().test_secure() @missing_feature(context.library < "java@1.13.0", reason="Not implemented yet") @missing_feature(library="python", reason="Not implemented yet") @@ -28,3 +36,17 @@ def test_telemetry_metric_instrumented_sink(self): @missing_feature(library="python", reason="Not implemented yet") def test_telemetry_metric_executed_sink(self): super().test_telemetry_metric_executed_sink() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestNoSqlMongodbInjection_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post("/iast/mongodb-nosql-injection/test_insecure", data={"key": "somevalue"}) + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_path_traversal.py b/tests/appsec/iast/sink/test_path_traversal.py index 2d2b706f64b..fd66fb82179 100644 --- a/tests/appsec/iast/sink/test_path_traversal.py +++ b/tests/appsec/iast/sink/test_path_traversal.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, missing_feature, features -from ..utils import BaseSinkTest +from utils import context, missing_feature, features, weblog, rfc +from ..utils import BaseSinkTest, validate_stack_traces @features.iast_sink_path_traversal @@ -17,7 +17,7 @@ class TestPathTraversal(BaseSinkTest): data = {"path": "/var/log"} location_map = { "java": "com.datadoghq.system_tests.iast.utils.PathExamples", - "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}, + "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"}, "python": {"flask-poc": "app.py", "django-poc": "app/urls.py"}, } @@ -34,3 +34,17 @@ def test_telemetry_metric_executed_sink(self): @missing_feature(library="nodejs", reason="Endpoint not implemented") def test_secure(self): return super().test_secure() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestPathTraversal_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post("/iast/path_traversal/test_insecure", data={"path": "/var/log"}) + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_reflection_injection.py b/tests/appsec/iast/sink/test_reflection_injection.py index a783085503b..4c32f4a2b9b 100644 --- a/tests/appsec/iast/sink/test_reflection_injection.py +++ b/tests/appsec/iast/sink/test_reflection_injection.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import missing_feature, features -from ..utils import BaseSinkTest +from utils import missing_feature, features, rfc, weblog +from ..utils import BaseSinkTest, validate_stack_traces @features.iast_sink_reflection_injection @@ -26,3 +26,17 @@ def test_telemetry_metric_executed_sink(self): def test_secure(self): super().test_secure() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestReflectionInjection_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post("/iast/reflection_injection/test_insecure", data={"param": "ReflectionInjection"}) + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_sql_injection.py b/tests/appsec/iast/sink/test_sql_injection.py index 702dd17379d..222e8ae3808 100644 --- a/tests/appsec/iast/sink/test_sql_injection.py +++ b/tests/appsec/iast/sink/test_sql_injection.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, missing_feature, features, bug -from ..utils import BaseSinkTest +from utils import context, missing_feature, features, bug, rfc, weblog +from ..utils import BaseSinkTest, validate_stack_traces @features.iast_sink_sql_injection @@ -17,15 +17,11 @@ class TestSqlInjection(BaseSinkTest): data = {"username": "shaquille_oatmeal", "password": "123456"} location_map = { "java": "com.datadoghq.system_tests.iast.utils.SqlExamples", - "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}, + "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"}, "python": {"flask-poc": "app.py", "django-poc": "app/urls.py"}, } - @bug( - context.library < "nodejs@5.3.0", - weblog_variant="express4-typescript", - reason="Incorrect vulnerability location", - ) + @bug(context.library < "nodejs@5.3.0", weblog_variant="express4-typescript", reason="APMRP-360") def test_insecure(self): super().test_insecure() @@ -43,3 +39,18 @@ def test_telemetry_metric_executed_sink(self): @missing_feature(context.weblog_variant == "jersey-grizzly2", reason="Endpoint responds 500") def test_secure(self): super().test_secure() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestSqlInjection_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post("/iast/sqli/test_insecure", data={"username": "shaquille_oatmeal", "password": "123456"}) + + @missing_feature(context.weblog_variant == "jersey-grizzly2", reason="Endpoint responds 500") + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_ssrf.py b/tests/appsec/iast/sink/test_ssrf.py index 54f0ebd2960..75ec87dafdc 100644 --- a/tests/appsec/iast/sink/test_ssrf.py +++ b/tests/appsec/iast/sink/test_ssrf.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import bug, context, missing_feature, features -from ..utils import BaseSinkTest +from utils import bug, context, missing_feature, features, rfc, weblog +from ..utils import BaseSinkTest, validate_stack_traces @features.iast_sink_ssrf @@ -17,11 +17,11 @@ class TestSSRF(BaseSinkTest): data = {"url": "https://www.datadoghq.com"} location_map = { "java": "com.datadoghq.system_tests.iast.utils.SsrfExamples", - "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}, + "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"}, "python": {"flask-poc": "app.py", "django-poc": "app/urls.py"}, } - @bug(context.library < "java@1.14.0", reason="https://github.com/DataDog/dd-trace-java/pull/5172") + @bug(context.library < "java@1.14.0", reason="APMRP-360") def test_insecure(self): super().test_insecure() @@ -34,3 +34,17 @@ def test_secure(self): @missing_feature(library="dotnet", reason="Not implemented yet") def test_telemetry_metric_instrumented_sink(self): super().test_telemetry_metric_instrumented_sink() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestSSRF_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post("/iast/ssrf/test_insecure", data={"url": "https://www.datadoghq.com"}) + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_template_injection.py b/tests/appsec/iast/sink/test_template_injection.py new file mode 100644 index 00000000000..b54dea2d1d8 --- /dev/null +++ b/tests/appsec/iast/sink/test_template_injection.py @@ -0,0 +1,18 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2021 Datadog, Inc. + +from utils import features +from ..utils import BaseSinkTest + + +@features.iast_sink_template_injection +class TestTemplateInjection(BaseSinkTest): + """Test template injection detection.""" + + vulnerability_type = "TEMPLATE_INJECTION" + http_method = "POST" + insecure_endpoint = "/iast/template_injection/test_insecure" + secure_endpoint = "/iast/template_injection/test_secure" + + data = {"template": "Hello"} diff --git a/tests/appsec/iast/sink/test_trust_boundary_violation.py b/tests/appsec/iast/sink/test_trust_boundary_violation.py index 18257e8b615..ede2601f657 100644 --- a/tests/appsec/iast/sink/test_trust_boundary_violation.py +++ b/tests/appsec/iast/sink/test_trust_boundary_violation.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import bug, context, missing_feature, features -from ..utils import BaseSinkTest +from utils import context, missing_feature, features, rfc, weblog +from ..utils import BaseSinkTest, validate_stack_traces @features.iast_sink_trustboundaryviolation @@ -26,3 +26,20 @@ def test_telemetry_metric_instrumented_sink(self): @missing_feature(context.library < "java@1.22.0", reason="Metrics not implemented") def test_telemetry_metric_executed_sink(self): super().test_telemetry_metric_executed_sink() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class Test_TrustBoundaryViolation_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.get( + "/iast/trust-boundary-violation/test_insecure", + params={"username": "shaquille_oatmeal", "password": "123456"}, + ) + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_untrusted_deserialization.py b/tests/appsec/iast/sink/test_untrusted_deserialization.py new file mode 100644 index 00000000000..b6fb11ede2d --- /dev/null +++ b/tests/appsec/iast/sink/test_untrusted_deserialization.py @@ -0,0 +1,31 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2021 Datadog, Inc. + +from utils import features, weblog, rfc +from ..utils import BaseSinkTest, validate_stack_traces + + +@features.iast_sink_untrusted_deserialization +class TestUntrustedDeserialization(BaseSinkTest): + """Test untrusted deserialization detection.""" + + vulnerability_type = "UNTRUSTED_DESERIALIZATION" + http_method = "GET" + insecure_endpoint = "/iast/untrusted_deserialization/test_insecure" + secure_endpoint = "/iast/untrusted_deserialization/test_secure" + location_map = {"java": "com.datadoghq.system_tests.iast.utils.DeserializationExamples"} + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestUntrustedDeserialization_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.get("/iast/untrusted_deserialization/test_insecure") + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_unvalidated_redirect.py b/tests/appsec/iast/sink/test_unvalidated_redirect.py index 8caaa393613..6caff555643 100644 --- a/tests/appsec/iast/sink/test_unvalidated_redirect.py +++ b/tests/appsec/iast/sink/test_unvalidated_redirect.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, irrelevant, features, missing_feature -from ..utils import BaseSinkTestWithoutTelemetry +from utils import context, irrelevant, features, missing_feature, rfc, weblog +from ..utils import BaseSinkTestWithoutTelemetry, validate_stack_traces def _expected_location(): @@ -19,7 +19,7 @@ def _expected_location(): if context.weblog_variant == "vertx4": return "com.datadoghq.vertx4.iast.routes.IastSinkRouteProvider" if context.library.library == "nodejs": - if context.weblog_variant == "express4": + if context.weblog_variant in ("express4", "express5"): return "iast/index.js" if context.weblog_variant == "express4-typescript": return "iast.ts" @@ -66,3 +66,36 @@ class TestUnvalidatedHeader(BaseSinkTestWithoutTelemetry): @missing_feature(context.weblog_variant == "vertx3", reason="Endpoint responds 403") def test_secure(self): return super().test_secure() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestUnvalidatedRedirect_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post( + "/iast/unvalidated_redirect/test_insecure_redirect", data={"location": "http://dummy.location.com"} + ) + + @irrelevant(library="java", weblog_variant="vertx3", reason="vertx3 redirects using location header") + def test_stack_trace(self): + validate_stack_traces(self.r) + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestUnvalidatedHeader_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post( + "/iast/unvalidated_redirect/test_insecure_header", data={"location": "http://dummy.location.com"} + ) + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_unvalidated_redirect_forward.py b/tests/appsec/iast/sink/test_unvalidated_redirect_forward.py index 9eefc343805..ca85e9cf69b 100644 --- a/tests/appsec/iast/sink/test_unvalidated_redirect_forward.py +++ b/tests/appsec/iast/sink/test_unvalidated_redirect_forward.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, features, missing_feature -from ..utils import BaseSinkTestWithoutTelemetry +from utils import context, features, missing_feature, rfc, weblog +from ..utils import BaseSinkTestWithoutTelemetry, validate_stack_traces def _expected_location(): @@ -30,3 +30,19 @@ class TestUnvalidatedForward(BaseSinkTestWithoutTelemetry): @missing_feature(library="java", reason="weblog responds 500") def test_secure(self): super().test_secure() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestUnvalidatedForward_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post( + "/iast/unvalidated_redirect/test_insecure_forward", data={"location": "http://dummy.location.com"} + ) + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_weak_cipher.py b/tests/appsec/iast/sink/test_weak_cipher.py index f9449246a6d..b2604f18abf 100644 --- a/tests/appsec/iast/sink/test_weak_cipher.py +++ b/tests/appsec/iast/sink/test_weak_cipher.py @@ -1,8 +1,8 @@ # Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, missing_feature, flaky, features -from ..utils import BaseSinkTest +from utils import context, missing_feature, flaky, features, weblog, rfc +from ..utils import BaseSinkTest, validate_stack_traces @features.weak_cipher_detection @@ -16,11 +16,11 @@ class TestWeakCipher(BaseSinkTest): data = None location_map = { "java": "com.datadoghq.system_tests.iast.utils.CryptoExamples", - "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}, + "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"}, } evidence_map = {"nodejs": "des-ede-cbc", "java": "Blowfish"} - @flaky(library="python", reason="PATH_TRAVERSAL on Crypto.Cipher.AES is reported, approx 10%") + @flaky(context.library == "dotnet@3.3.1", reason="APMRP-360") def test_secure(self): super().test_secure() @@ -32,3 +32,17 @@ def test_telemetry_metric_instrumented_sink(self): @missing_feature(context.library < "java@1.11.0", reason="Metrics not implemented") def test_telemetry_metric_executed_sink(self): super().test_telemetry_metric_executed_sink() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestWeakCipher_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.get("/iast/insecure_cipher/test_insecure_algorithm") + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_weak_hash.py b/tests/appsec/iast/sink/test_weak_hash.py index 4ef4d33e734..ecc322da203 100644 --- a/tests/appsec/iast/sink/test_weak_hash.py +++ b/tests/appsec/iast/sink/test_weak_hash.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import weblog, context, bug, missing_feature, features -from ..utils import BaseSinkTest, assert_iast_vulnerability +from utils import weblog, context, missing_feature, features, rfc, scenarios +from ..utils import BaseSinkTest, assert_iast_vulnerability, validate_stack_traces def _expected_location(): @@ -11,7 +11,7 @@ def _expected_location(): return "com.datadoghq.system_tests.iast.utils.CryptoExamples" if context.library.library == "nodejs": - if context.weblog_variant == "express4": + if context.weblog_variant in ("express4", "express5"): return "iast/index.js" if context.weblog_variant == "express4-typescript": return "iast.ts" @@ -46,10 +46,42 @@ class TestWeakHash(BaseSinkTest): location_map = _expected_location() evidence_map = _expected_evidence() + @missing_feature(context.library < "java@1.9.0", reason="Metrics not implemented") + @missing_feature(library="dotnet", reason="Not implemented yet") + def test_telemetry_metric_instrumented_sink(self): + super().test_telemetry_metric_instrumented_sink() + + @missing_feature(context.library < "java@1.11.0", reason="Metrics not implemented") + @missing_feature(context.library < "dotnet@2.38.0", reason="Not implemented yet") + def test_telemetry_metric_executed_sink(self): + super().test_telemetry_metric_executed_sink() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestWeakHash_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.get("/iast/insecure_hashing/test_md5_algorithm") + + def test_stack_trace(self): + validate_stack_traces(self.r) + + +@scenarios.iast_deduplication +@features.weak_hash_vulnerability_detection +class TestDeduplication: + """Verify vulnerability deduplication.""" + + location_map = _expected_location() + evidence_map = _expected_evidence() + def setup_insecure_hash_remove_duplicates(self): self.r_insecure_hash_remove_duplicates = weblog.get("/iast/insecure_hashing/deduplicate") - @missing_feature(weblog_variant="spring-boot-openliberty") def test_insecure_hash_remove_duplicates(self): """If one line is vulnerable and it is executed multiple times (for instance in a loop) in a request, we will report only one vulnerability""" @@ -57,29 +89,18 @@ def test_insecure_hash_remove_duplicates(self): request=self.r_insecure_hash_remove_duplicates, vulnerability_count=1, vulnerability_type="WEAK_HASH", - expected_location=self.expected_location, - expected_evidence=self.expected_evidence, + expected_location=_expected_location(), + expected_evidence=_expected_evidence(), ) def setup_insecure_hash_multiple(self): self.r_insecure_hash_multiple = weblog.get("/iast/insecure_hashing/multiple_hash") - @bug(weblog_variant="spring-boot-openliberty") def test_insecure_hash_multiple(self): """If a endpoint has multiple vulnerabilities (in diferent lines) we will report all of them""" assert_iast_vulnerability( request=self.r_insecure_hash_multiple, vulnerability_count=2, vulnerability_type="WEAK_HASH", - expected_location=self.expected_location, + expected_location=_expected_location(), ) - - @missing_feature(context.library < "java@1.9.0", reason="Metrics not implemented") - @missing_feature(library="dotnet", reason="Not implemented yet") - def test_telemetry_metric_instrumented_sink(self): - super().test_telemetry_metric_instrumented_sink() - - @missing_feature(context.library < "java@1.11.0", reason="Metrics not implemented") - @missing_feature(context.library < "dotnet@2.38.0", reason="Not implemented yet") - def test_telemetry_metric_executed_sink(self): - super().test_telemetry_metric_executed_sink() diff --git a/tests/appsec/iast/sink/test_weak_randomness.py b/tests/appsec/iast/sink/test_weak_randomness.py index 1aed825dc17..893441b4088 100644 --- a/tests/appsec/iast/sink/test_weak_randomness.py +++ b/tests/appsec/iast/sink/test_weak_randomness.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import features -from ..utils import BaseSinkTestWithoutTelemetry +from utils import features, weblog, rfc +from ..utils import BaseSinkTestWithoutTelemetry, validate_stack_traces @features.iast_sink_weakrandomness @@ -18,5 +18,19 @@ class TestWeakRandomness(BaseSinkTestWithoutTelemetry): location_map = { "java": "com.datadoghq.system_tests.iast.utils.WeakRandomnessExamples", "python": {"flask-poc": "app.py", "django-poc": "app/urls.py"}, - "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts"}, + "nodejs": {"express4": "iast/index.js", "express4-typescript": "iast.ts", "express5": "iast/index.js"}, } + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestWeakRandomness_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.get("/iast/weak_randomness/test_insecure") + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_xcontent_sniffing.py b/tests/appsec/iast/sink/test_xcontent_sniffing.py index c24a2cd261b..77e996ca0d7 100644 --- a/tests/appsec/iast/sink/test_xcontent_sniffing.py +++ b/tests/appsec/iast/sink/test_xcontent_sniffing.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, missing_feature, features -from ..utils import BaseSinkTest +from utils import context, missing_feature, features, rfc, weblog +from ..utils import BaseSinkTest, validate_stack_traces @features.iast_sink_xcontentsniffing @@ -23,3 +23,17 @@ def test_telemetry_metric_instrumented_sink(self): @missing_feature(context.library < "java@1.22.0", reason="Metrics not implemented") def test_telemetry_metric_executed_sink(self): super().test_telemetry_metric_executed_sink() + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class Test_XContentSniffing_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.get("/iast/xcontent-missing-header/test_insecure") + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_xpath_injection.py b/tests/appsec/iast/sink/test_xpath_injection.py index 14a880cdb8c..3add0f480b6 100644 --- a/tests/appsec/iast/sink/test_xpath_injection.py +++ b/tests/appsec/iast/sink/test_xpath_injection.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import features -from ..utils import BaseSinkTestWithoutTelemetry +from utils import features, weblog, rfc +from ..utils import BaseSinkTestWithoutTelemetry, validate_stack_traces @features.iast_sink_xpathinjection @@ -16,3 +16,17 @@ class TestXPathInjection(BaseSinkTestWithoutTelemetry): secure_endpoint = "/iast/xpathi/test_secure" data = {"expression": "expression"} location_map = {"java": "com.datadoghq.system_tests.iast.utils.XPathExamples"} + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestXPathInjection_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post("/iast/xpathi/test_insecure", data={"expression": "expression"}) + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/sink/test_xss.py b/tests/appsec/iast/sink/test_xss.py index b004c879c90..74449793c7c 100644 --- a/tests/appsec/iast/sink/test_xss.py +++ b/tests/appsec/iast/sink/test_xss.py @@ -2,8 +2,8 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import features -from ..utils import BaseSinkTestWithoutTelemetry +from utils import features, weblog, rfc +from ..utils import BaseSinkTestWithoutTelemetry, validate_stack_traces @features.iast_sink_xss @@ -16,3 +16,17 @@ class TestXSS(BaseSinkTestWithoutTelemetry): secure_endpoint = "/iast/xss/test_secure" data = {"param": "param"} location_map = {"java": "com.datadoghq.system_tests.iast.utils.XSSExamples"} + + +@rfc( + "https://docs.google.com/document/d/1ga7yCKq2htgcwgQsInYZKktV0hNlv4drY9XzSxT-o5U/edit?tab=t.0#heading=h.d0f5wzmlfhat" +) +@features.iast_stack_trace +class TestXSS_StackTrace: + """Validate stack trace generation""" + + def setup_stack_trace(self): + self.r = weblog.post("/iast/xss/test_insecure", data={"param": "param"}) + + def test_stack_trace(self): + validate_stack_traces(self.r) diff --git a/tests/appsec/iast/source/test_body.py b/tests/appsec/iast/source/test_body.py index 87582e2c880..9fe98ba9af7 100644 --- a/tests/appsec/iast/source/test_body.py +++ b/tests/appsec/iast/source/test_body.py @@ -16,8 +16,7 @@ class TestRequestBody(BaseSourceTest): source_names = None source_value = None - @bug(weblog_variant="jersey-grizzly2", reason="Not reported") - @missing_feature(library="python", reason="Not implemented yet") + @bug(weblog_variant="jersey-grizzly2", reason="APPSEC-56007") def test_source_reported(self): super().test_source_reported() @@ -26,9 +25,8 @@ def test_source_reported(self): context.library < "java@1.22.0" and "spring-boot" not in context.weblog_variant, reason="Metrics not implemented", ) - @bug(context.library >= "java@1.13.0" and context.library < "java@1.17.0", reason="Not reported") + @bug(context.library >= "java@1.13.0" and context.library < "java@1.17.0", reason="APMRP-360") @missing_feature(library="dotnet", reason="Not implemented yet") - @missing_feature(library="python", reason="Not implemented yet") def test_telemetry_metric_instrumented_source(self): super().test_telemetry_metric_instrumented_source() @@ -38,6 +36,5 @@ def test_telemetry_metric_instrumented_source(self): reason="Metrics not implemented", ) @missing_feature(library="dotnet", reason="Not implemented yet") - @missing_feature(library="python", reason="Not implemented yet") def test_telemetry_metric_executed_source(self): super().test_telemetry_metric_executed_source() diff --git a/tests/appsec/iast/source/test_cookie_name.py b/tests/appsec/iast/source/test_cookie_name.py index 1fab94aea4e..cc3016b6541 100644 --- a/tests/appsec/iast/source/test_cookie_name.py +++ b/tests/appsec/iast/source/test_cookie_name.py @@ -11,10 +11,10 @@ class TestCookieName(BaseSourceTest): """Verify that request cookies are tainted""" endpoint = "/iast/source/cookiename/test" - requests_kwargs = [{"method": "GET", "cookies": {"user": "unused"}}] + requests_kwargs = [{"method": "GET", "cookies": {"table": "unused"}}] source_type = "http.request.cookie.name" - source_names = ["user"] - source_value = "user" + source_names = ["table"] + source_value = "table" @missing_feature(library="dotnet", reason="Not implemented") @missing_feature(context.library < "java@1.9.0", reason="Metrics not implemented") @@ -22,7 +22,7 @@ class TestCookieName(BaseSourceTest): context.library < "java@1.22.0" and "spring-boot" not in context.weblog_variant, reason="Metrics not implemented", ) - @bug(context.library >= "java@1.16.0" and context.library < "java@1.22.0", reason="Not working as expected") + @bug(context.library >= "java@1.16.0" and context.library < "java@1.22.0", reason="APMRP-360") @missing_feature(weblog_variant="akka-http", reason="Not working as expected") def test_telemetry_metric_instrumented_source(self): super().test_telemetry_metric_instrumented_source() diff --git a/tests/appsec/iast/source/test_header_value.py b/tests/appsec/iast/source/test_header_value.py index a011afe85fd..579ea92aec7 100644 --- a/tests/appsec/iast/source/test_header_value.py +++ b/tests/appsec/iast/source/test_header_value.py @@ -20,10 +20,6 @@ class TestHeaderValue(BaseSourceTest): source_value = "user" @missing_feature(context.library < "java@1.9.0", reason="Metrics not implemented") - @missing_feature( - context.library.library == "java" and "spring-boot" not in context.weblog_variant, - reason="Metrics not implemented", - ) @missing_feature(library="dotnet", reason="Not implemented") def test_telemetry_metric_instrumented_source(self): super().test_telemetry_metric_instrumented_source() diff --git a/tests/appsec/iast/source/test_kafka_key.py b/tests/appsec/iast/source/test_kafka_key.py index a45dc73feff..06530135c74 100644 --- a/tests/appsec/iast/source/test_kafka_key.py +++ b/tests/appsec/iast/source/test_kafka_key.py @@ -2,7 +2,7 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import features, scenarios +from utils import features, scenarios, flaky, context from ..utils import BaseSourceTest, get_all_iast_events, get_iast_sources diff --git a/tests/appsec/iast/source/test_kafka_value.py b/tests/appsec/iast/source/test_kafka_value.py index 0b22493f158..eefde19671a 100644 --- a/tests/appsec/iast/source/test_kafka_value.py +++ b/tests/appsec/iast/source/test_kafka_value.py @@ -2,7 +2,7 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import features, scenarios +from utils import features, scenarios, flaky, context from ..utils import BaseSourceTest, get_all_iast_events, get_iast_sources diff --git a/tests/appsec/iast/source/test_parameter_name.py b/tests/appsec/iast/source/test_parameter_name.py index 1d8160639b2..ba7d29c0dfd 100644 --- a/tests/appsec/iast/source/test_parameter_name.py +++ b/tests/appsec/iast/source/test_parameter_name.py @@ -21,26 +21,32 @@ class TestParameterName(BaseSourceTest): setup_source_post_reported = BaseSourceTest.setup_source_reported - @missing_feature(weblog_variant="express4", reason="Tainted as request body") - @bug(weblog_variant="resteasy-netty3", reason="Not reported") - @bug(library="python", reason="Python frameworks need a header, if not, 415 status code") + @missing_feature( + context.library == "nodejs" and context.weblog_variant in ["express4", "express5"], + reason="Tainted as request body", + ) + @bug(weblog_variant="resteasy-netty3", reason="APPSEC-55687") + @bug(library="python", reason="APPSEC-55689") @missing_feature(library="dotnet", reason="Tainted as request body") def test_source_post_reported(self): - """ for use case where only one is reported, we want to keep a test on the one reported """ + """for use case where only one is reported, we want to keep a test on the one reported""" self.validate_request_reported(self.requests["POST"]) setup_source_get_reported = BaseSourceTest.setup_source_reported - @bug(weblog_variant="jersey-grizzly2", reason="Not reported") - @bug(weblog_variant="resteasy-netty3", reason="Not reported") + @bug(context.library < "java@1.40.0" and context.weblog_variant == "jersey-grizzly2", reason="APPSEC-55387") + @bug(weblog_variant="resteasy-netty3", reason="APPSEC-55687") def test_source_get_reported(self): - """ for use case where only one is reported, we want to keep a test on the one reported """ + """for use case where only one is reported, we want to keep a test on the one reported""" self.validate_request_reported(self.requests["GET"]) - @missing_feature(weblog_variant="express4", reason="Tainted as request body") - @bug(weblog_variant="jersey-grizzly2", reason="Not reported") - @bug(weblog_variant="resteasy-netty3", reason="Not reported") - @bug(library="python", reason="Python frameworks need a header, if not, 415 status code") + @missing_feature( + context.library == "nodejs" and context.weblog_variant in ["express4", "express5"], + reason="Tainted as request body", + ) + @bug(context.library < "java@1.40.0" and context.weblog_variant == "jersey-grizzly2", reason="APPSEC-55387") + @bug(weblog_variant="resteasy-netty3", reason="APPSEC-55687") + @bug(library="python", reason="APPSEC-55689") @missing_feature(library="dotnet", reason="Tainted as request body") def test_source_reported(self): super().test_source_reported() diff --git a/tests/appsec/iast/source/test_parameter_value.py b/tests/appsec/iast/source/test_parameter_value.py index 5cc99c9b15f..e9367dd3aab 100644 --- a/tests/appsec/iast/source/test_parameter_value.py +++ b/tests/appsec/iast/source/test_parameter_value.py @@ -2,7 +2,7 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import context, missing_feature, bug, features +from utils import context, missing_feature, irrelevant, features, flaky from ..utils import BaseSourceTest @@ -29,7 +29,12 @@ class TestParameterValue(BaseSourceTest): setup_source_post_reported = BaseSourceTest.setup_source_reported - @bug(library="python", reason="Python frameworks need a header, if not, 415 status code") + @irrelevant( + library="python", + reason="Flask and Django need a header; otherwise, they return a 415 status code." + "TODO: When FastAPI implements POST body source, verify if it does too.", + ) + @flaky(context.weblog_variant == "resteasy-netty3", reason="APPSEC-56007") def test_source_post_reported(self): self.validate_request_reported(self.requests["POST"]) @@ -39,9 +44,6 @@ def test_source_get_reported(self): self.validate_request_reported(self.requests["GET"], source_type="http.request.parameter") @missing_feature(context.library < "java@1.9.0", reason="Not implemented") - @missing_feature( - context.library == "java" and not context.weblog_variant.startswith("spring-boot"), reason="Not implemented" - ) @missing_feature( context.library < "java@1.22.0" and "spring-boot" not in context.weblog_variant, reason="Metrics not implemented", diff --git a/tests/appsec/iast/source/test_path_parameter.py b/tests/appsec/iast/source/test_path_parameter.py new file mode 100644 index 00000000000..4aa61b05258 --- /dev/null +++ b/tests/appsec/iast/source/test_path_parameter.py @@ -0,0 +1,17 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2021 Datadog, Inc. + +from utils import features +from ..utils import BaseSourceTest + + +@features.iast_source_path_parameter +class TestPathParameter(BaseSourceTest): + """Verify that request path is tainted""" + + endpoint = "/iast/source/path_parameter/test/user" + source_type = "http.request.path.parameter" + source_names = ["table"] + source_value = "user" + requests_kwargs = [{"method": "GET"}] diff --git a/tests/appsec/iast/source/test_sql_row.py b/tests/appsec/iast/source/test_sql_row.py new file mode 100644 index 00000000000..df96159f00d --- /dev/null +++ b/tests/appsec/iast/source/test_sql_row.py @@ -0,0 +1,16 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2021 Datadog, Inc. + +from utils import features +from ..utils import BaseSourceTest + + +@features.iast_source_sql +class TestSqlRow(BaseSourceTest): + """Verify that database source is tainted""" + + endpoint = "/iast/source/sql/test" + source_type = "sql.row.value" + source_names = ["0.username"] + requests_kwargs = [{"method": "GET"}] diff --git a/tests/appsec/iast/utils.py b/tests/appsec/iast/utils.py index 2675757ab80..330205f4952 100644 --- a/tests/appsec/iast/utils.py +++ b/tests/appsec/iast/utils.py @@ -1,6 +1,6 @@ import json from utils import weblog, interfaces, context -from utils.tools import logging +from utils.tools import logger def _get_expectation(d): @@ -21,17 +21,18 @@ def _get_span_meta(request): assert spans, "No root span found" span = spans[0] meta = span.get("meta", {}) - return meta + meta_struct = span.get("meta_struct", {}) + return meta, meta_struct def get_iast_event(request): - meta = _get_span_meta(request=request) - assert "_dd.iast.json" in meta, "No _dd.iast.json tag in span" - return meta["_dd.iast.json"] + meta, meta_struct = _get_span_meta(request=request) + assert "_dd.iast.json" in meta or "iast" in meta_struct, "No IAST info found tag in span" + return meta.get("_dd.iast.json") or meta_struct.get("iast") def assert_iast_vulnerability( - request, vulnerability_count=1, vulnerability_type=None, expected_location=None, expected_evidence=None + request, vulnerability_count=None, vulnerability_type=None, expected_location=None, expected_evidence=None ): iast = get_iast_event(request=request) assert iast["vulnerabilities"], "Expected at least one vulnerability" @@ -45,7 +46,8 @@ def assert_iast_vulnerability( if expected_evidence: vulns = [v for v in vulns if v.get("evidence", {}).get("value", "") == expected_evidence] assert vulns, f"No vulnerability with evidence value {expected_evidence}" - assert len(vulns) == vulnerability_count + if vulnerability_count is not None: + assert len(vulns) == vulnerability_count def _check_telemetry_response_from_agent(): @@ -56,7 +58,7 @@ def _check_telemetry_response_from_agent(): code = data["response"]["status_code"] if code != 200: filename = data["log_filename"] - logging.warning(f"Agent answered {code} on {filename}, it may cause telemetry issues") + logger.warning(f"Agent answered {code} on {filename}, it may cause telemetry issues") return @@ -103,7 +105,6 @@ def expected_evidence(self): return _get_expectation(self.evidence_map) def setup_insecure(self): - # optimize by attaching requests to the class object, to avoid calling it several times. We can't attach them # to self, and we need to attach the request on class object, as there are one class instance by test case @@ -123,7 +124,6 @@ def setup_insecure(self): def test_insecure(self): assert_iast_vulnerability( request=self.insecure_request, - vulnerability_count=1, vulnerability_type=self.vulnerability_type, expected_location=self.expected_location, expected_evidence=self.expected_evidence, @@ -137,7 +137,6 @@ def check_test_insecure(self): self.test_insecure() def setup_secure(self): - # optimize by attaching requests to the class object, to avoid calling it several times. We can't attach them # to self, and we need to attach the request on class object, as there are one class instance by test case @@ -159,14 +158,86 @@ def test_secure(self): # to avoid false positive, we need to check first that the insecure endpoint is vulnerable self.check_test_insecure() - self.assert_no_iast_event(self.secure_request) + self.assert_no_iast_event(self.secure_request, self.vulnerability_type) @staticmethod - def assert_no_iast_event(request): + def assert_no_iast_event(request, tested_vulnerability_type=None): assert request.status_code == 200, f"Request failed with status code {request.status_code}" - meta = _get_span_meta(request=request) - iast_json = meta.get("_dd.iast.json") - assert iast_json is None, f"Unexpected vulnerabilities reported: {iast_json}" + + for data, _, span in interfaces.library.get_spans(request=request): + logger.info(f"Looking for IAST events in {data['log_filename']}") + meta, meta_struct = _get_span_meta(request=request) + iast_json = meta.get("_dd.iast.json") if meta else meta_struct.get("iast") + if iast_json is not None: + if tested_vulnerability_type is None: + logger.error(json.dumps(iast_json, indent=2)) + raise ValueError("Unexpected vulnerability reported") + elif iast_json["vulnerabilities"]: + for vuln in iast_json["vulnerabilities"]: + if vuln["type"] == tested_vulnerability_type: + logger.error(json.dumps(iast_json, indent=2)) + raise ValueError(f"Unexpected vulnerability reported: {vuln['type']}") + + +def validate_stack_traces(request): + spans = [span for _, span in interfaces.library.get_root_spans(request=request)] + assert spans, "No root span found" + span = spans[0] + meta = span.get("meta", {}) + assert "_dd.iast.json" in meta, "No iast event in root span" + iast = meta["_dd.iast.json"] + assert iast["vulnerabilities"], "Expected at least one vulnerability" + + # To simplify as we are relaying in insecure_request that is expected to have one vulnerability + vuln = iast["vulnerabilities"][0] + + assert vuln["stackId"], "no 'stack_id's present'" + assert "meta_struct" in span, "'meta_struct' not found in span" + assert "_dd.stack" in span["meta_struct"], "'_dd.stack' not found in 'meta_struct'" + assert "vulnerability" in span["meta_struct"]["_dd.stack"], "'exploit' not found in '_dd.stack'" + + stack_trace = span["meta_struct"]["_dd.stack"]["vulnerability"][0] + assert stack_trace, "No stack traces to validate" + + assert "language" in stack_trace, "'language' not found in stack trace" + assert stack_trace["language"] in ( + "php", + "python", + "nodejs", + "java", + "dotnet", + "go", + "ruby", + ), "unexpected language" + + # Ensure the stack ID corresponds to an appsec event + assert "id" in stack_trace, "'id' not found in stack trace" + assert stack_trace["id"] == vuln["stackId"], "'id' doesn't correspond to an appsec event" + + assert "frames" in stack_trace, "'frames' not found in stack trace" + assert len(stack_trace["frames"]) <= 32, "stack trace above size limit (32 frames)" + + # Vulns without location path are not expected to have a stack trace + location = vuln["location"] + assert location is not None and "path" in location, "This vulnerability is not expected to have a stack trace" + + locationFrame = None + for frame in stack_trace["frames"]: + # We are looking for the frame that corresponds to the location of the vulnerability, we will need to update this to cover all tracers + # currently support: Java, Python + if ( + stack_trace["language"] == "java" + and ( + location["path"] in frame["class_name"] + and location["method"] in frame["function"] + and location["line"] == frame["line"] + ) + ) or ( + stack_trace["language"] == "python" + and (frame.get("file", "").endswith(location["path"]) and location["line"] == frame["line"]) + ): + locationFrame = frame + assert locationFrame is not None, "location not found in stack trace" class BaseSinkTest(BaseSinkTestWithoutTelemetry): @@ -182,7 +253,7 @@ def test_telemetry_metric_instrumented_sink(self): expected_metric = "instrumented.sink" series = interfaces.library.get_telemetry_metric_series(expected_namespace, expected_metric) assert series, f"Got no series for metric {expected_metric}" - logging.debug("Series: %s", series) + logger.debug("Series: %s", series) # lower the vulnerability_type, as all assertion will be case-insensitive expected_tag = f"vulnerability_type:{self.vulnerability_type}".lower() @@ -213,7 +284,7 @@ def test_telemetry_metric_executed_sink(self): expected_metric = "executed.sink" series = interfaces.library.get_telemetry_metric_series(expected_namespace, expected_metric) assert series, f"Got no series for metric {expected_metric}" - logging.debug("Series: %s", series) + logger.debug("Series: %s", series) # lower the vulnerability_type, as all assertion will be case-insensitive expected_tag = f"vulnerability_type:{self.vulnerability_type}".lower() @@ -319,7 +390,7 @@ def test_telemetry_metric_instrumented_source(self): expected_metric = "instrumented.source" series = interfaces.library.get_telemetry_metric_series(expected_namespace, expected_metric) assert series, f"Got no series for metric {expected_metric}" - logging.debug(f"Series: {json.dumps(series, indent=2)}") + logger.debug(f"Series: {json.dumps(series, indent=2)}") # lower the source_type, as all assertion will be case-insensitive expected_tag = f"source_type:{self.source_type}".lower() @@ -358,7 +429,7 @@ def test_telemetry_metric_executed_source(self): assert len(series) != 0, f"Got no series for metric {expected_metric} with tag {expected_tag}" - logging.debug(f"Series:\n{json.dumps(series, indent=2)}") + logger.debug(f"Series:\n{json.dumps(series, indent=2)}") for s in series: assert s["_computed_namespace"] == expected_namespace @@ -368,3 +439,24 @@ def test_telemetry_metric_executed_source(self): assert len(s["points"]) == 1 p = s["points"][0] assert p[1] >= 1 + + +class BaseTestCookieNameFilter: + vulnerability_type = None + endpoint = None + + def setup_cookie_name_filter(self): + prefix = "0" * 36 + cookieName1 = prefix + "name1" + cookieName2 = "name2" + cookieName3 = prefix + "name3" + self.req1 = weblog.post(self.endpoint, data={"cookieName": cookieName1, "cookieValue": "value1"}) + self.req2 = weblog.post(self.endpoint, data={"cookieName": cookieName2, "cookieValue": "value2"}) + self.req3 = weblog.post(self.endpoint, data={"cookieName": cookieName3, "cookieValue": "value3"}) + + def test_cookie_name_filter(self): + assert_iast_vulnerability(request=self.req1, vulnerability_count=1, vulnerability_type=self.vulnerability_type) + assert_iast_vulnerability(request=self.req2, vulnerability_count=1, vulnerability_type=self.vulnerability_type) + + meta, meta_struct = _get_span_meta(self.req3) + assert "_dd.iast.json" not in meta and "iast" not in meta_struct, "No IAST info expected in span" diff --git a/utils/build/docker/ruby/rails32/app/models/.gitkeep b/tests/appsec/rasp/__init__.py similarity index 100% rename from utils/build/docker/ruby/rails32/app/models/.gitkeep rename to tests/appsec/rasp/__init__.py diff --git a/tests/appsec/rasp/rasp_ruleset.json b/tests/appsec/rasp/rasp_ruleset.json index 38bdc164e41..658edea7fb1 100644 --- a/tests/appsec/rasp/rasp_ruleset.json +++ b/tests/appsec/rasp/rasp_ruleset.json @@ -179,6 +179,104 @@ "on_match": [ "stack_trace", "block" ] - } + }, + { + "id": "rasp-932-100", + "name": "Shell injection exploit", + "enabled": true, + "tags": { + "type": "command_injection", + "category": "vulnerability_trigger", + "cwe": "77", + "capec": "1000/152/248/88", + "confidence": "0", + "module": "rasp" + }, + "conditions": [ + { + "parameters": { + "resource": [ + { + "address": "server.sys.shell.cmd" + } + ], + "params": [ + { + "address": "server.request.query" + }, + { + "address": "server.request.body" + }, + { + "address": "server.request.path_params" + }, + { + "address": "grpc.server.request.message" + }, + { + "address": "graphql.server.all_resolvers" + }, + { + "address": "graphql.server.resolver" + } + ] + }, + "operator": "shi_detector" + } + ], + "transformers": [], + "on_match": [ + "stack_trace", "block" + ] + }, + { + "id": "rasp-932-110", + "name": "OS command injection exploit", + "enabled": true, + "tags": { + "type": "command_injection", + "category": "vulnerability_trigger", + "cwe": "77", + "capec": "1000/152/248/88", + "confidence": "0", + "module": "rasp" + }, + "conditions": [ + { + "parameters": { + "resource": [ + { + "address": "server.sys.exec.cmd" + } + ], + "params": [ + { + "address": "server.request.query" + }, + { + "address": "server.request.body" + }, + { + "address": "server.request.path_params" + }, + { + "address": "grpc.server.request.message" + }, + { + "address": "graphql.server.all_resolvers" + }, + { + "address": "graphql.server.resolver" + } + ] + }, + "operator": "cmdi_detector" + } + ], + "transformers": [], + "on_match": [ + "stack_trace", "block" + ] + } ] } diff --git a/tests/appsec/rasp/test_cmdi.py b/tests/appsec/rasp/test_cmdi.py new file mode 100644 index 00000000000..78cffb62f2b --- /dev/null +++ b/tests/appsec/rasp/test_cmdi.py @@ -0,0 +1,241 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2021 Datadog, Inc. + +from utils import features, weblog, interfaces, scenarios, rfc +from utils.dd_constants import Capabilities +from tests.appsec.rasp.utils import ( + validate_span_tags, + validate_stack_traces, + find_series, + validate_metric_variant, + Base_Rules_Version, + Base_WAF_Version, +) + + +@rfc("https://docs.google.com/document/d/1DDWy3frMXDTAbk-BfnZ1FdRwuPx6Pl7AWyR4zjqRFZw") +@features.rasp_command_injection +@scenarios.appsec_rasp +class Test_Cmdi_UrlQuery: + """Command Injection through query parameters""" + + def setup_cmdi_get(self): + self.r = weblog.get("/rasp/cmdi", params={"command": "/usr/bin/touch /tmp/passwd"}) + + def test_cmdi_get(self): + assert self.r.status_code == 403 + + interfaces.library.assert_rasp_attack( + self.r, + "rasp-932-110", + { + "resource": { + "address": "server.sys.exec.cmd", + "value": "/usr/bin/touch /tmp/passwd", + }, + "params": { + "address": "server.request.query", + "value": "/usr/bin/touch /tmp/passwd", + }, + }, + ) + + +@rfc("https://docs.google.com/document/d/1DDWy3frMXDTAbk-BfnZ1FdRwuPx6Pl7AWyR4zjqRFZw") +@features.rasp_command_injection +@scenarios.appsec_rasp +class Test_Cmdi_BodyUrlEncoded: + """Command Injection through a url-encoded body parameter""" + + def setup_cmdi_post_urlencoded(self): + self.r = weblog.post("/rasp/cmdi", data={"command": "/usr/bin/touch /tmp/passwd"}) + + def test_cmdi_post_urlencoded(self): + assert self.r.status_code == 403 + + interfaces.library.assert_rasp_attack( + self.r, + "rasp-932-110", + { + "resource": { + "address": "server.sys.exec.cmd", + "value": "/usr/bin/touch /tmp/passwd", + }, + "params": { + "address": "server.request.body", + "value": "/usr/bin/touch /tmp/passwd", + }, + }, + ) + + +@rfc("https://docs.google.com/document/d/1DDWy3frMXDTAbk-BfnZ1FdRwuPx6Pl7AWyR4zjqRFZw") +@features.rasp_command_injection +@scenarios.appsec_rasp +class Test_Cmdi_BodyXml: + """Command Injection through an xml body parameter""" + + def setup_cmdi_post_xml(self): + data = ( + "/usr/bin/touch/tmp/passwd" + ) + self.r = weblog.post("/rasp/cmdi", data=data, headers={"Content-Type": "application/xml"}) + + def test_cmdi_post_xml(self): + assert self.r.status_code == 403 + + interfaces.library.assert_rasp_attack( + self.r, + "rasp-932-110", + { + "resource": {"address": "server.sys.exec.cmd", "value": '/usr/bin/touch "/tmp/passwd"'}, + "params": {"address": "server.request.body", "value": "/usr/bin/touch"}, + }, + ) + + +@rfc("https://docs.google.com/document/d/1DDWy3frMXDTAbk-BfnZ1FdRwuPx6Pl7AWyR4zjqRFZw") +@features.rasp_command_injection +@scenarios.appsec_rasp +class Test_Cmdi_BodyJson: + """Command Injection through a json body parameter""" + + def setup_cmdi_post_json(self): + """AppSec detects attacks in JSON body values""" + self.r = weblog.post("/rasp/cmdi", json={"command": ["/usr/bin/touch", "/tmp/passwd"]}) + + def test_cmdi_post_json(self): + assert self.r.status_code == 403 + + interfaces.library.assert_rasp_attack( + self.r, + "rasp-932-110", + { + "resource": { + "address": "server.sys.exec.cmd", + "value": '/usr/bin/touch "/tmp/passwd"', + }, + "params": { + "address": "server.request.body", + "value": "/usr/bin/touch", + }, + }, + ) + + +@rfc("https://docs.google.com/document/d/1DDWy3frMXDTAbk-BfnZ1FdRwuPx6Pl7AWyR4zjqRFZw") +@features.rasp_span_tags +@features.rasp_command_injection +@scenarios.appsec_rasp +class Test_Cmdi_Mandatory_SpanTags: + """Validate span tag generation on exploit attempts""" + + def setup_cmdi_span_tags(self): + self.r = weblog.get("/rasp/cmdi", params={"command": "/usr/bin/touch /tmp/passwd"}) + + def test_cmdi_span_tags(self): + validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration"]) + + +@rfc("https://docs.google.com/document/d/1DDWy3frMXDTAbk-BfnZ1FdRwuPx6Pl7AWyR4zjqRFZw") +@features.rasp_span_tags +@features.rasp_command_injection +@scenarios.appsec_rasp +class Test_Cmdi_Optional_SpanTags: + """Validate span tag generation on exploit attempts""" + + def setup_cmdi_span_tags(self): + self.r = weblog.get("/rasp/cmdi", params={"command": "/usr/bin/touch /tmp/passwd"}) + + def test_cmdi_span_tags(self): + validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration_ext", "_dd.appsec.rasp.rule.eval"]) + + +@rfc("https://docs.google.com/document/d/1DDWy3frMXDTAbk-BfnZ1FdRwuPx6Pl7AWyR4zjqRFZw") +@features.rasp_stack_trace +@features.rasp_command_injection +@scenarios.appsec_rasp +class Test_Cmdi_StackTrace: + """Validate stack trace generation on exploit attempts""" + + def setup_cmdi_stack_trace(self): + self.r = weblog.get("/rasp/cmdi", params={"command": "/usr/bin/touch /tmp/passwd"}) + + def test_cmdi_stack_trace(self): + assert self.r.status_code == 403 + validate_stack_traces(self.r) + + +@rfc("https://docs.google.com/document/d/1DDWy3frMXDTAbk-BfnZ1FdRwuPx6Pl7AWyR4zjqRFZw") +@features.rasp_command_injection +@scenarios.appsec_rasp +class Test_Cmdi_Telemetry: + """Validate Telemetry data on exploit attempts""" + + def setup_cmdi_telemetry(self): + self.r = weblog.get("/rasp/cmdi", params={"command": "/usr/bin/touch /tmp/passwd"}) + + def test_cmdi_telemetry(self): + assert self.r.status_code == 403 + + series_eval = find_series(True, "appsec", "rasp.rule.eval") + assert series_eval + assert any(validate_metric_variant("rasp.rule.eval", "command_injection", "exec", s) for s in series_eval), [ + s.get("tags") for s in series_eval + ] + + series_match = find_series(True, "appsec", "rasp.rule.match") + assert series_match + assert any(validate_metric_variant("rasp.rule.match", "command_injection", "exec", s) for s in series_match), [ + s.get("tags") for s in series_match + ] + + +@rfc("https://docs.google.com/document/d/1DDWy3frMXDTAbk-BfnZ1FdRwuPx6Pl7AWyR4zjqRFZw") +@features.rasp_command_injection +@scenarios.appsec_rasp +class Test_Cmdi_Telemetry_Variant_Tag: + """Validate Telemetry data variant tag on exploit attempts""" + + def setup_cmdi_telemetry(self): + self.r = weblog.get("/rasp/cmdi", params={"command": "/usr/bin/touch /tmp/passwd"}) + + def test_cmdi_telemetry(self): + assert self.r.status_code == 403 + + series_eval = find_series(True, "appsec", "rasp.rule.eval") + assert series_eval + assert any(validate_metric_variant("rasp.rule.eval", "command_injection", "exec", s) for s in series_eval), [ + s.get("tags") for s in series_eval + ] + + series_match = find_series(True, "appsec", "rasp.rule.match") + assert series_match + assert any(validate_metric_variant("rasp.rule.match", "command_injection", "exec", s) for s in series_match), [ + s.get("tags") for s in series_match + ] + + +@rfc("https://docs.google.com/document/d/1DDWy3frMXDTAbk-BfnZ1FdRwuPx6Pl7AWyR4zjqRFZw") +@features.rasp_command_injection +@scenarios.remote_config_mocked_backend_asm_dd +class Test_Cmdi_Capability: + """Validate that ASM_RASP_CMDI (37) capability is sent""" + + def test_cmdi_capability(self): + interfaces.library.assert_rc_capability(Capabilities.ASM_RASP_CMDI) + + +@features.rasp_command_injection +class Test_Cmdi_Rules_Version(Base_Rules_Version): + """Test cmdi min rules version""" + + min_version = "1.13.3" + + +@features.rasp_command_injection +class Test_Cmdi_Waf_Version(Base_WAF_Version): + """Test cmdi WAF version""" + + min_version = "1.21.0" diff --git a/tests/appsec/rasp/test_lfi.py b/tests/appsec/rasp/test_lfi.py index 4e7b2344b0d..3af0533e8e6 100644 --- a/tests/appsec/rasp/test_lfi.py +++ b/tests/appsec/rasp/test_lfi.py @@ -3,13 +3,24 @@ # Copyright 2021 Datadog, Inc. from utils import features, weblog, interfaces, scenarios, rfc +from utils import remote_config as rc +from utils.dd_constants import Capabilities +from tests.appsec.rasp.utils import ( + validate_span_tags, + validate_stack_traces, + find_series, + validate_metric, + RC_CONSTANTS, + Base_Rules_Version, + Base_WAF_Version, +) @rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.3nydvvu7sn93") @features.rasp_local_file_inclusion @scenarios.appsec_rasp class Test_Lfi_UrlQuery: - """ Local file inclusion through query parameters """ + """Local file inclusion through query parameters""" def setup_lfi_get(self): self.r = weblog.get("/rasp/lfi", params={"file": "../etc/passwd"}) @@ -31,7 +42,7 @@ def test_lfi_get(self): @features.rasp_local_file_inclusion @scenarios.appsec_rasp class Test_Lfi_BodyUrlEncoded: - """ Local file inclusion through a url-encoded body parameter """ + """Local file inclusion through a url-encoded body parameter""" def setup_lfi_post_urlencoded(self): self.r = weblog.post("/rasp/lfi", data={"file": "../etc/passwd"}) @@ -53,7 +64,7 @@ def test_lfi_post_urlencoded(self): @features.rasp_local_file_inclusion @scenarios.appsec_rasp class Test_Lfi_BodyXml: - """ Local file inclusion through an xml body parameter """ + """Local file inclusion through an xml body parameter""" def setup_lfi_post_xml(self): data = "../etc/passwd" @@ -76,7 +87,7 @@ def test_lfi_post_xml(self): @features.rasp_local_file_inclusion @scenarios.appsec_rasp class Test_Lfi_BodyJson: - """ Local file inclusion through a json body parameter """ + """Local file inclusion through a json body parameter""" def setup_lfi_post_json(self): """AppSec detects attacks in JSON body values""" @@ -93,3 +104,169 @@ def test_lfi_post_json(self): "params": {"address": "server.request.body", "value": "../etc/passwd"}, }, ) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") +@features.rasp_span_tags +@features.rasp_local_file_inclusion +@scenarios.appsec_rasp +class Test_Lfi_Mandatory_SpanTags: + """Validate span tag generation on exploit attempts""" + + def setup_lfi_span_tags(self): + self.r = weblog.get("/rasp/lfi", params={"file": "../etc/passwd"}) + + def test_lfi_span_tags(self): + validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration"]) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") +@features.rasp_span_tags +@features.rasp_local_file_inclusion +@scenarios.appsec_rasp +class Test_Lfi_Optional_SpanTags: + """Validate span tag generation on exploit attempts""" + + def setup_lfi_span_tags(self): + self.r = weblog.get("/rasp/lfi", params={"file": "../etc/passwd"}) + + def test_lfi_span_tags(self): + validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration_ext", "_dd.appsec.rasp.rule.eval"]) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.enmf90juqidf") +@features.rasp_stack_trace +@features.rasp_local_file_inclusion +@scenarios.appsec_rasp +class Test_Lfi_StackTrace: + """Validate stack trace generation on exploit attempts""" + + def setup_lfi_stack_trace(self): + self.r = weblog.get("/rasp/lfi", params={"file": "../etc/passwd"}) + + def test_lfi_stack_trace(self): + validate_stack_traces(self.r) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") +@features.rasp_local_file_inclusion +@scenarios.appsec_rasp +class Test_Lfi_Telemetry: + """Validate Telemetry data on exploit attempts""" + + def setup_lfi_telemetry(self): + self.r = weblog.get("/rasp/lfi", params={"file": "../etc/passwd"}) + + def test_lfi_telemetry(self): + series_eval = find_series(True, "appsec", "rasp.rule.eval") + assert series_eval + assert any(validate_metric("rasp.rule.eval", "lfi", s) for s in series_eval), [ + s.get("tags") for s in series_eval + ] + + series_match = find_series(True, "appsec", "rasp.rule.match") + assert series_match + assert any(validate_metric("rasp.rule.match", "lfi", s) for s in series_match), [ + s.get("tags") for s in series_match + ] + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.3nydvvu7sn93") +@features.rasp_local_file_inclusion +@scenarios.appsec_runtime_activation +class Test_Lfi_RC_CustomAction: + """Local file inclusion through query parameters""" + + def setup_lfi_get(self): + self.config_state_1 = rc.rc_state.reset().set_config(*RC_CONSTANTS.CONFIG_ENABLED).apply() + self.config_state_1b = rc.rc_state.set_config(*RC_CONSTANTS.RULES).apply() + self.r1 = weblog.get("/rasp/lfi", params={"file": "../etc/passwd"}) + + self.config_state_2 = rc.rc_state.set_config(*RC_CONSTANTS.BLOCK_505).apply() + self.r2 = weblog.get("/rasp/lfi", params={"file": "../etc/passwd"}) + + self.config_state_3 = rc.rc_state.set_config(*RC_CONSTANTS.BLOCK_REDIRECT).apply() + self.r3 = weblog.get("/rasp/lfi", params={"file": "../etc/passwd"}, allow_redirects=False) + + self.config_state_4 = rc.rc_state.del_config(RC_CONSTANTS.BLOCK_REDIRECT[0]).apply() + self.r4 = weblog.get("/rasp/lfi", params={"file": "../etc/passwd"}) + + self.config_state_5 = rc.rc_state.reset().apply() + self.r5 = weblog.get("/rasp/lfi", params={"file": "../etc/passwd"}) + + def test_lfi_get(self): + assert self.config_state_1[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.config_state_1b[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.r1.status_code == 403 + interfaces.library.assert_rasp_attack( + self.r1, + "rasp-930-100", + { + "resource": {"address": "server.io.fs.file", "value": "../etc/passwd"}, + "params": {"address": "server.request.query", "value": "../etc/passwd"}, + }, + ) + + assert self.config_state_2[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.r2.status_code == 505 + interfaces.library.assert_rasp_attack( + self.r2, + "rasp-930-100", + { + "resource": {"address": "server.io.fs.file", "value": "../etc/passwd"}, + "params": {"address": "server.request.query", "value": "../etc/passwd"}, + }, + ) + + assert self.config_state_3[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.r3.status_code == 302 + assert self.r3.headers["Location"] == "http://google.com" + + interfaces.library.assert_rasp_attack( + self.r3, + "rasp-930-100", + { + "resource": {"address": "server.io.fs.file", "value": "../etc/passwd"}, + "params": {"address": "server.request.query", "value": "../etc/passwd"}, + }, + ) + + assert self.config_state_4[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.r4.status_code == 403 + interfaces.library.assert_rasp_attack( + self.r4, + "rasp-930-100", + { + "resource": {"address": "server.io.fs.file", "value": "../etc/passwd"}, + "params": {"address": "server.request.query", "value": "../etc/passwd"}, + }, + ) + + assert self.config_state_5[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.r5.status_code == 200 + + interfaces.library.assert_no_appsec_event(self.r5) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.mshauo3jp6wh") +@features.rasp_local_file_inclusion +@scenarios.remote_config_mocked_backend_asm_dd +class Test_Lfi_Capability: + """Validate that ASM_RASP_LFI (22) capability is sent""" + + def test_lfi_capability(self): + interfaces.library.assert_rc_capability(Capabilities.ASM_RASP_LFI) + + +@features.rasp_local_file_inclusion +class Test_Lfi_Rules_Version(Base_Rules_Version): + """Test lfi min rules version""" + + min_version = "1.13.3" + + +@features.rasp_local_file_inclusion +class Test_Lfi_Waf_Version(Base_WAF_Version): + """Test lfi WAF version""" + + min_version = "1.20.1" diff --git a/tests/appsec/rasp/test_shi.py b/tests/appsec/rasp/test_shi.py new file mode 100644 index 00000000000..53bbbb4967c --- /dev/null +++ b/tests/appsec/rasp/test_shi.py @@ -0,0 +1,225 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2021 Datadog, Inc. + +from utils import features, weblog, interfaces, scenarios, rfc, context +from utils.dd_constants import Capabilities +from tests.appsec.rasp.utils import ( + validate_span_tags, + validate_stack_traces, + find_series, + validate_metric, + validate_metric_variant, + Base_Rules_Version, + Base_WAF_Version, +) + + +class Test_Shi_Base: + def get_shell_value(self): + # This is a workaround for java as command injection is not supporting String commands yet, we need to use the shell injection heuristics + if context.library == "java": + return "$(cat /etc/passwd 1>&2 ; echo .)" + return "ls $(cat /etc/passwd 1>&2 ; echo .)" + + +@rfc("https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx") +@features.rasp_shell_injection +@scenarios.appsec_rasp +class Test_Shi_UrlQuery(Test_Shi_Base): + """Shell Injection through query parameters""" + + def setup_shi_get(self): + self.r = weblog.get("/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}) + + def test_shi_get(self): + assert self.r.status_code == 403 + + interfaces.library.assert_rasp_attack( + self.r, + "rasp-932-100", + { + "resource": {"address": "server.sys.shell.cmd", "value": self.get_shell_value()}, + "params": {"address": "server.request.query", "value": "$(cat /etc/passwd 1>&2 ; echo .)"}, + }, + ) + + +@rfc("https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx") +@features.rasp_shell_injection +@scenarios.appsec_rasp +class Test_Shi_BodyUrlEncoded(Test_Shi_Base): + """Shell Injection through a url-encoded body parameter""" + + def setup_shi_post_urlencoded(self): + self.r = weblog.post("/rasp/shi", data={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}) + + def test_shi_post_urlencoded(self): + assert self.r.status_code == 403 + + interfaces.library.assert_rasp_attack( + self.r, + "rasp-932-100", + { + "resource": {"address": "server.sys.shell.cmd", "value": self.get_shell_value()}, + "params": {"address": "server.request.body", "value": "$(cat /etc/passwd 1>&2 ; echo .)"}, + }, + ) + + +@rfc("https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx") +@features.rasp_shell_injection +@scenarios.appsec_rasp +class Test_Shi_BodyXml(Test_Shi_Base): + """Shell Injection through an xml body parameter""" + + def setup_shi_post_xml(self): + data = "$(cat /etc/passwd 1>&2 ; echo .)" + self.r = weblog.post("/rasp/shi", data=data, headers={"Content-Type": "application/xml"}) + + def test_shi_post_xml(self): + assert self.r.status_code == 403 + + interfaces.library.assert_rasp_attack( + self.r, + "rasp-932-100", + { + "resource": {"address": "server.sys.shell.cmd", "value": self.get_shell_value()}, + "params": {"address": "server.request.body", "value": "$(cat /etc/passwd 1>&2 ; echo .)"}, + }, + ) + + +@rfc("https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx") +@features.rasp_shell_injection +@scenarios.appsec_rasp +class Test_Shi_BodyJson(Test_Shi_Base): + """Shell Injection through a json body parameter""" + + def setup_shi_post_json(self): + """AppSec detects attacks in JSON body values""" + self.r = weblog.post("/rasp/shi", json={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}) + + def test_shi_post_json(self): + assert self.r.status_code == 403 + + interfaces.library.assert_rasp_attack( + self.r, + "rasp-932-100", + { + "resource": {"address": "server.sys.shell.cmd", "value": self.get_shell_value()}, + "params": {"address": "server.request.body", "value": "$(cat /etc/passwd 1>&2 ; echo .)"}, + }, + ) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") +@features.rasp_span_tags +@features.rasp_shell_injection +@scenarios.appsec_rasp +class Test_Shi_Mandatory_SpanTags: + """Validate span tag generation on exploit attempts""" + + def setup_shi_span_tags(self): + self.r = weblog.get("/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}) + + def test_shi_span_tags(self): + validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration"]) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") +@features.rasp_span_tags +@features.rasp_shell_injection +@scenarios.appsec_rasp +class Test_Shi_Optional_SpanTags: + """Validate span tag generation on exploit attempts""" + + def setup_shi_span_tags(self): + self.r = weblog.get("/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}) + + def test_shi_span_tags(self): + validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration_ext", "_dd.appsec.rasp.rule.eval"]) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.enmf90juqidf") +@features.rasp_stack_trace +@features.rasp_shell_injection +@scenarios.appsec_rasp +class Test_Shi_StackTrace: + """Validate stack trace generation on exploit attempts""" + + def setup_shi_stack_trace(self): + self.r = weblog.get("/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}) + + def test_shi_stack_trace(self): + validate_stack_traces(self.r) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") +@features.rasp_shell_injection +@scenarios.appsec_rasp +class Test_Shi_Telemetry: + """Validate Telemetry data on exploit attempts""" + + def setup_shi_telemetry(self): + self.r = weblog.get("/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}) + + def test_shi_telemetry(self): + series_eval = find_series(True, "appsec", "rasp.rule.eval") + assert series_eval + assert any(validate_metric("rasp.rule.eval", "command_injection", s) for s in series_eval), [ + s.get("tags") for s in series_eval + ] + + series_match = find_series(True, "appsec", "rasp.rule.match") + assert series_match + assert any(validate_metric("rasp.rule.match", "command_injection", s) for s in series_match), [ + s.get("tags") for s in series_match + ] + + +@rfc("https://docs.google.com/document/d/1DDWy3frMXDTAbk-BfnZ1FdRwuPx6Pl7AWyR4zjqRFZw") +@features.rasp_shell_injection +@scenarios.appsec_rasp +class Test_Shi_Telemetry_Variant_Tag: + """Validate Telemetry data variant tag on exploit attempts""" + + def setup_shi_telemetry(self): + self.r = weblog.get("/rasp/shi", params={"list_dir": "$(cat /etc/passwd 1>&2 ; echo .)"}) + + def test_shi_telemetry(self): + series_eval = find_series(True, "appsec", "rasp.rule.eval") + assert series_eval + assert any(validate_metric_variant("rasp.rule.eval", "command_injection", "shell", s) for s in series_eval), [ + s.get("tags") for s in series_eval + ] + + series_match = find_series(True, "appsec", "rasp.rule.match") + assert series_match + assert any(validate_metric_variant("rasp.rule.match", "command_injection", "shell", s) for s in series_match), [ + s.get("tags") for s in series_match + ] + + +@rfc("https://docs.google.com/document/d/1gCXU3LvTH9en3Bww0AC2coSJWz1m7HcavZjvMLuDCWg/edit#heading=h.giijrtyn1fdx") +@features.rasp_shell_injection +@scenarios.remote_config_mocked_backend_asm_dd +class Test_Shi_Capability: + """Validate that ASM_RASP_SHI (24) capability is sent""" + + def test_shi_capability(self): + interfaces.library.assert_rc_capability(Capabilities.ASM_RASP_SHI) + + +@features.rasp_local_file_inclusion +class Test_Shi_Rules_Version(Base_Rules_Version): + """Test shi min rules version""" + + min_version = "1.13.1" + + +@features.rasp_local_file_inclusion +class Test_Shi_Waf_Version(Base_WAF_Version): + """Test shi WAF version""" + + min_version = "1.20.1" diff --git a/tests/appsec/rasp/test_span_tags.py b/tests/appsec/rasp/test_span_tags.py deleted file mode 100644 index da4d67532b0..00000000000 --- a/tests/appsec/rasp/test_span_tags.py +++ /dev/null @@ -1,76 +0,0 @@ -# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. -# This product includes software developed at Datadog (https://www.datadoghq.com/). -# Copyright 2021 Datadog, Inc. - -from utils import features, weblog, interfaces, scenarios, rfc, missing_feature - - -def validate_span_tags(request, expected_meta=[], expected_metrics=[]): - """Validate RASP span tags are added when an event is generated""" - spans = [s for _, s in interfaces.library.get_root_spans(request=request)] - assert spans, "No spans to validate" - - for span in spans: - meta = span["meta"] - for m in expected_meta: - assert m in meta, f"missing span meta tag `{m}` in {meta}" - - metrics = span["metrics"] - for m in expected_metrics: - assert m in metrics, f"missing span metric tag `{m}` in {metrics}" - - -@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") -@features.rasp_span_tags -@scenarios.appsec_rasp -class Test_Mandatory_SpanTags: - """ Validate span tag generation on exploit attempts """ - - def setup_lfi_span_tags(self): - self.r = weblog.get("/rasp/lfi", params={"file": "../etc/passwd"}) - - @missing_feature(library="nodejs", reason="Not supported yet") - def test_lfi_span_tags(self): - validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration"]) - - def setup_ssrf_span_tags(self): - self.r = weblog.get("/rasp/ssrf", params={"domain": "169.254.169.254"}) - - def test_ssrf_span_tags(self): - validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration"]) - - def setup_sqli_span_tags(self): - self.r = weblog.get("/rasp/sqli", params={"user_id": "' OR 1 = 1 --"}) - - @missing_feature(library="dotnet") - @missing_feature(library="nodejs", reason="Not supported yet") - def test_sqli_span_tags(self): - validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration"]) - - -@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") -@features.rasp_span_tags -@scenarios.appsec_rasp -class Test_Optional_SpanTags: - """ Validate span tag generation on exploit attempts """ - - def setup_lfi_span_tags(self): - self.r = weblog.get("/rasp/lfi", params={"file": "../etc/passwd"}) - - @missing_feature(library="nodejs", reason="Not supported yet") - def test_lfi_span_tags(self): - validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration_ext", "_dd.appsec.rasp.rule.eval"]) - - def setup_ssrf_span_tags(self): - self.r = weblog.get("/rasp/ssrf", params={"domain": "169.254.169.254"}) - - def test_ssrf_span_tags(self): - validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration_ext", "_dd.appsec.rasp.rule.eval"]) - - def setup_sqli_span_tags(self): - self.r = weblog.get("/rasp/sqli", params={"user_id": "' OR 1 = 1 --"}) - - @missing_feature(library="dotnet") - @missing_feature(library="nodejs", reason="Not supported yet") - def test_sqli_span_tags(self): - validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration_ext", "_dd.appsec.rasp.rule.eval"]) diff --git a/tests/appsec/rasp/test_sqli.py b/tests/appsec/rasp/test_sqli.py index d1447b6631e..6578158dd4c 100644 --- a/tests/appsec/rasp/test_sqli.py +++ b/tests/appsec/rasp/test_sqli.py @@ -2,14 +2,23 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import features, weblog, interfaces, scenarios, rfc +from utils import features, weblog, interfaces, scenarios, rfc, context +from utils.dd_constants import Capabilities +from tests.appsec.rasp.utils import ( + validate_span_tags, + validate_stack_traces, + find_series, + validate_metric, + Base_Rules_Version, + Base_WAF_Version, +) @rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.gv4kwto3561e") @features.rasp_sql_injection @scenarios.appsec_rasp class Test_Sqli_UrlQuery: - """ SQL Injection through query parameters """ + """SQL Injection through query parameters""" def setup_sqli_get(self): self.r = weblog.get("/rasp/sqli", params={"user_id": "' OR 1 = 1 --"}) @@ -21,7 +30,7 @@ def test_sqli_get(self): self.r, "rasp-942-100", { - "resource": {"address": "server.db.statement", "value": "SELECT * FROM users WHERE ? OR ? = ? --"}, + "resource": {"address": "server.db.statement", "value": "SELECT * FROM users WHERE id=? OR ? = ? --'"}, "params": {"address": "server.request.query", "value": "' OR 1 = 1 --"}, "db_type": {"address": "server.db.system"}, }, @@ -32,7 +41,7 @@ def test_sqli_get(self): @features.rasp_sql_injection @scenarios.appsec_rasp class Test_Sqli_BodyUrlEncoded: - """ SQL Injection through a url-encoded body parameter """ + """SQL Injection through a url-encoded body parameter""" def setup_sqli_post_urlencoded(self): self.r = weblog.post("/rasp/sqli", data={"user_id": "' OR 1 = 1 --"}) @@ -44,7 +53,7 @@ def test_sqli_post_urlencoded(self): self.r, "rasp-942-100", { - "resource": {"address": "server.db.statement", "value": "SELECT * FROM users WHERE ? OR ? = ? --"}, + "resource": {"address": "server.db.statement", "value": "SELECT * FROM users WHERE id=? OR ? = ? --'"}, "params": {"address": "server.request.body", "value": "' OR 1 = 1 --"}, "db_type": {"address": "server.db.system"}, }, @@ -55,7 +64,7 @@ def test_sqli_post_urlencoded(self): @features.rasp_sql_injection @scenarios.appsec_rasp class Test_Sqli_BodyXml: - """ SQL Injection through an xml body parameter """ + """SQL Injection through an xml body parameter""" def setup_sqli_post_xml(self): data = "' OR 1 = 1 --" @@ -68,7 +77,7 @@ def test_sqli_post_xml(self): self.r, "rasp-942-100", { - "resource": {"address": "server.db.statement", "value": "SELECT * FROM users WHERE ? OR ? = ? --"}, + "resource": {"address": "server.db.statement", "value": "SELECT * FROM users WHERE id=? OR ? = ? --'"}, "params": {"address": "server.request.body", "value": "' OR 1 = 1 --"}, "db_type": {"address": "server.db.system"}, }, @@ -79,7 +88,7 @@ def test_sqli_post_xml(self): @features.rasp_sql_injection @scenarios.appsec_rasp class Test_Sqli_BodyJson: - """ SQL Injection through a json body parameter """ + """SQL Injection through a json body parameter""" def setup_sqli_post_json(self): """AppSec detects attacks in JSON body values""" @@ -92,8 +101,97 @@ def test_sqli_post_json(self): self.r, "rasp-942-100", { - "resource": {"address": "server.db.statement", "value": "SELECT * FROM users WHERE ? OR ? = ? --"}, + "resource": {"address": "server.db.statement", "value": "SELECT * FROM users WHERE id=? OR ? = ? --'"}, "params": {"address": "server.request.body", "value": "' OR 1 = 1 --"}, "db_type": {"address": "server.db.system"}, }, ) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") +@features.rasp_span_tags +@features.rasp_sql_injection +@scenarios.appsec_rasp +class Test_Sqli_Mandatory_SpanTags: + """Validate span tag generation on exploit attempts""" + + def setup_sqli_span_tags(self): + self.r = weblog.get("/rasp/sqli", params={"user_id": "' OR 1 = 1 --"}) + + def test_sqli_span_tags(self): + validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration"]) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") +@features.rasp_span_tags +@features.rasp_sql_injection +@scenarios.appsec_rasp +class Test_Sqli_Optional_SpanTags: + """Validate span tag generation on exploit attempts""" + + def setup_sqli_span_tags(self): + self.r = weblog.get("/rasp/sqli", params={"user_id": "' OR 1 = 1 --"}) + + def test_sqli_span_tags(self): + validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration_ext", "_dd.appsec.rasp.rule.eval"]) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.enmf90juqidf") +@features.rasp_stack_trace +@features.rasp_sql_injection +@scenarios.appsec_rasp +class Test_Sqli_StackTrace: + """Validate stack trace generation on exploit attempts""" + + def setup_sqli_stack_trace(self): + self.r = weblog.get("/rasp/sqli", params={"user_id": "' OR 1 = 1 --"}) + + def test_sqli_stack_trace(self): + validate_stack_traces(self.r) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") +@features.rasp_sql_injection +@scenarios.appsec_rasp +class Test_Sqli_Telemetry: + """Validate Telemetry data on exploit attempts""" + + def setup_sqli_telemetry(self): + self.r = weblog.get("/rasp/sqli", params={"user_id": "' OR 1 = 1 --"}) + + def test_sqli_telemetry(self): + series_eval = find_series(True, "appsec", "rasp.rule.eval") + assert series_eval + assert any(validate_metric("rasp.rule.eval", "sql_injection", s) for s in series_eval), [ + s.get("tags") for s in series_eval + ] + + series_match = find_series(True, "appsec", "rasp.rule.match") + assert series_match + assert any(validate_metric("rasp.rule.match", "sql_injection", s) for s in series_match), [ + s.get("tags") for s in series_match + ] + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.mshauo3jp6wh") +@features.rasp_sql_injection +@scenarios.remote_config_mocked_backend_asm_dd +class Test_Sqli_Capability: + """Validate that ASM_RASP_SQLI (21) capability is sent""" + + def test_sqli_capability(self): + interfaces.library.assert_rc_capability(Capabilities.ASM_RASP_SQLI) + + +@features.rasp_local_file_inclusion +class Test_Sqli_Rules_Version(Base_Rules_Version): + """Test Sqli min rules version""" + + min_version = "1.13.2" + + +@features.rasp_local_file_inclusion +class Test_Sqli_Waf_Version(Base_WAF_Version): + """Test sqli WAF version""" + + min_version = "1.20.1" diff --git a/tests/appsec/rasp/test_ssrf.py b/tests/appsec/rasp/test_ssrf.py index 894cbc57fba..46386df3e5e 100644 --- a/tests/appsec/rasp/test_ssrf.py +++ b/tests/appsec/rasp/test_ssrf.py @@ -2,14 +2,23 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import features, weblog, interfaces, scenarios, rfc +from utils import features, weblog, interfaces, scenarios, rfc, context +from utils.dd_constants import Capabilities +from tests.appsec.rasp.utils import ( + validate_span_tags, + validate_stack_traces, + find_series, + validate_metric, + Base_Rules_Version, + Base_WAF_Version, +) @rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.3r1lwuv4y2g3") @features.rasp_server_side_request_forgery @scenarios.appsec_rasp class Test_Ssrf_UrlQuery: - """ Server-side request forgery through query parameters """ + """Server-side request forgery through query parameters""" def setup_ssrf_get(self): self.r = weblog.get("/rasp/ssrf", params={"domain": "169.254.169.254"}) @@ -17,11 +26,15 @@ def setup_ssrf_get(self): def test_ssrf_get(self): assert self.r.status_code == 403 + expected_http_value = "http://169.254.169.254" + if context.library == "nodejs": + expected_http_value += "/" + interfaces.library.assert_rasp_attack( self.r, "rasp-934-100", { - "resource": {"address": "server.io.net.url", "value": "http://169.254.169.254"}, + "resource": {"address": "server.io.net.url", "value": expected_http_value}, "params": {"address": "server.request.query", "value": "169.254.169.254"}, }, ) @@ -31,7 +44,7 @@ def test_ssrf_get(self): @features.rasp_server_side_request_forgery @scenarios.appsec_rasp class Test_Ssrf_BodyUrlEncoded: - """ Server-side request forgery through a url-encoded body parameter """ + """Server-side request forgery through a url-encoded body parameter""" def setup_ssrf_post_urlencoded(self): self.r = weblog.post("/rasp/ssrf", data={"domain": "169.254.169.254"}) @@ -39,12 +52,22 @@ def setup_ssrf_post_urlencoded(self): def test_ssrf_post_urlencoded(self): assert self.r.status_code == 403 + expected_http_value = "http://169.254.169.254" + if context.library == "nodejs": + expected_http_value += "/" + interfaces.library.assert_rasp_attack( self.r, "rasp-934-100", { - "resource": {"address": "server.io.net.url", "value": "http://169.254.169.254"}, - "params": {"address": "server.request.body", "value": "169.254.169.254"}, + "resource": { + "address": "server.io.net.url", + "value": expected_http_value, + }, + "params": { + "address": "server.request.body", + "value": "169.254.169.254", + }, }, ) @@ -53,10 +76,10 @@ def test_ssrf_post_urlencoded(self): @features.rasp_server_side_request_forgery @scenarios.appsec_rasp class Test_Ssrf_BodyXml: - """ Server-side request forgery through an xml body parameter """ + """Server-side request forgery through an xml body parameter""" def setup_ssrf_post_xml(self): - data = f"169.254.169.254" + data = "169.254.169.254" self.r = weblog.post("/rasp/ssrf", data=data, headers={"Content-Type": "application/xml"}) def test_ssrf_post_xml(self): @@ -66,8 +89,14 @@ def test_ssrf_post_xml(self): self.r, "rasp-934-100", { - "resource": {"address": "server.io.net.url", "value": "http://169.254.169.254"}, - "params": {"address": "server.request.body", "value": "169.254.169.254"}, + "resource": { + "address": "server.io.net.url", + "value": "http://169.254.169.254", + }, + "params": { + "address": "server.request.body", + "value": "169.254.169.254", + }, }, ) @@ -76,7 +105,7 @@ def test_ssrf_post_xml(self): @features.rasp_server_side_request_forgery @scenarios.appsec_rasp class Test_Ssrf_BodyJson: - """ Server-side request forgery through a json body parameter """ + """Server-side request forgery through a json body parameter""" def setup_ssrf_post_json(self): """AppSec detects attacks in JSON body values""" @@ -85,11 +114,116 @@ def setup_ssrf_post_json(self): def test_ssrf_post_json(self): assert self.r.status_code == 403 + expected_http_value = "http://169.254.169.254" + if context.library == "nodejs": + expected_http_value += "/" + interfaces.library.assert_rasp_attack( self.r, "rasp-934-100", { - "resource": {"address": "server.io.net.url", "value": "http://169.254.169.254"}, - "params": {"address": "server.request.body", "value": "169.254.169.254"}, + "resource": { + "address": "server.io.net.url", + "value": expected_http_value, + }, + "params": { + "address": "server.request.body", + "value": "169.254.169.254", + }, }, ) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") +@features.rasp_span_tags +@features.rasp_server_side_request_forgery +@scenarios.appsec_rasp +class Test_Ssrf_Mandatory_SpanTags: + """Validate span tag generation on exploit attempts""" + + def setup_ssrf_span_tags(self): + self.r = weblog.get("/rasp/ssrf", params={"domain": "169.254.169.254"}) + + def test_ssrf_span_tags(self): + validate_span_tags(self.r, expected_metrics=["_dd.appsec.rasp.duration"]) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") +@features.rasp_span_tags +@features.rasp_server_side_request_forgery +@scenarios.appsec_rasp +class Test_Ssrf_Optional_SpanTags: + """Validate span tag generation on exploit attempts""" + + def setup_ssrf_span_tags(self): + self.r = weblog.get("/rasp/ssrf", params={"domain": "169.254.169.254"}) + + def test_ssrf_span_tags(self): + validate_span_tags( + self.r, + expected_metrics=[ + "_dd.appsec.rasp.duration_ext", + "_dd.appsec.rasp.rule.eval", + ], + ) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.enmf90juqidf") +@features.rasp_stack_trace +@features.rasp_server_side_request_forgery +@scenarios.appsec_rasp +class Test_Ssrf_StackTrace: + """Validate stack trace generation on exploit attempts""" + + def setup_ssrf_stack_trace(self): + self.r = weblog.get("/rasp/ssrf", params={"domain": "169.254.169.254"}) + + def test_ssrf_stack_trace(self): + validate_stack_traces(self.r) + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.96mezjnqf46y") +@features.rasp_server_side_request_forgery +@scenarios.appsec_rasp +class Test_Ssrf_Telemetry: + """Validate Telemetry data on exploit attempts""" + + def setup_ssrf_telemetry(self): + self.r = weblog.get("/rasp/ssrf", params={"domain": "169.254.169.254"}) + + def test_ssrf_telemetry(self): + series_eval = find_series(True, "appsec", "rasp.rule.eval") + assert series_eval + assert any(validate_metric("rasp.rule.eval", "ssrf", s) for s in series_eval), [ + s.get("tags") for s in series_eval + ] + + series_match = find_series(True, "appsec", "rasp.rule.match") + assert series_match + assert any(validate_metric("rasp.rule.match", "ssrf", s) for s in series_match), [ + s.get("tags") for s in series_match + ] + + +@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.mshauo3jp6wh") +@features.rasp_server_side_request_forgery +@scenarios.remote_config_mocked_backend_asm_dd +class Test_Ssrf_Capability: + """Validate that ASM_RASP_SSRF (23) capability is sent""" + + def test_ssrf_capability(self): + interfaces.library.assert_rc_capability(Capabilities.ASM_RASP_SSRF) + + +@features.rasp_local_file_inclusion +class Test_Ssrf_Rules_Version(Base_Rules_Version): + """Test ssrf min rules version""" + + min_version = "1.13.2" + + +@features.rasp_local_file_inclusion +class Test_Ssrf_Waf_Version(Base_WAF_Version): + """Test ssrf WAF version""" + + min_version = "1.20.1" diff --git a/tests/appsec/rasp/test_stack_traces.py b/tests/appsec/rasp/test_stack_traces.py deleted file mode 100644 index c62c22637d1..00000000000 --- a/tests/appsec/rasp/test_stack_traces.py +++ /dev/null @@ -1,82 +0,0 @@ -# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. -# This product includes software developed at Datadog (https://www.datadoghq.com/). -# Copyright 2021 Datadog, Inc. - -from utils import features, weblog, interfaces, scenarios, rfc, missing_feature - - -def validate_stack_traces(request): - spans = [s for _, s in interfaces.library.get_root_spans(request=request)] - assert spans, "No spans to validate" - - for span in spans: - assert "_dd.appsec.json" in span["meta"], "'_dd.appsec.json' not found in 'meta'" - - json = span["meta"]["_dd.appsec.json"] - assert "triggers" in json, "'triggers' not found in '_dd.appsec.json'" - - triggers = json["triggers"] - - # Find all stack IDs - stack_ids = [] - for event in triggers: - if "stack_id" in event: - stack_ids.append(event["stack_id"]) - - # The absence of stack IDs can be considered a bug - assert len(stack_ids) > 0, "no 'stack_id's present in 'triggers'" - - assert "meta_struct" in span, "'meta_struct' not found in span" - assert "_dd.stack" in span["meta_struct"], "'_dd.stack' not found in 'meta_struct'" - assert "exploit" in span["meta_struct"]["_dd.stack"], "'exploit' not found in '_dd.stack'" - - stack_traces = span["meta_struct"]["_dd.stack"]["exploit"] - assert stack_traces, "No stack traces to validate" - - for stack in stack_traces: - assert "language" in stack, "'language' not found in stack trace" - assert stack["language"] in ( - "php", - "python", - "nodejs", - "java", - "dotnet", - "go", - "ruby", - ), "unexpected language" - - # Ensure the stack ID corresponds to an appsec event - assert "id" in stack, "'id' not found in stack trace" - assert stack["id"] in stack_ids, "'id' doesn't correspond to an appsec event" - - assert "frames" in stack, "'frames' not found in stack trace" - assert len(stack["frames"]) <= 32, "stack trace above size limit (32 frames)" - - -@rfc("https://docs.google.com/document/d/1vmMqpl8STDk7rJnd3YBsa6O9hCls_XHHdsodD61zr_4/edit#heading=h.enmf90juqidf") -@features.rasp_stack_trace -@scenarios.appsec_rasp -class Test_StackTrace: - """ Validate stack trace generation on exploit attempts """ - - def setup_lfi_stack_trace(self): - self.r = weblog.get("/rasp/lfi", params={"file": "../etc/passwd"}) - - def test_lfi_stack_trace(self): - assert self.r.status_code == 403 - validate_stack_traces(self.r) - - def setup_ssrf_stack_trace(self): - self.r = weblog.get("/rasp/ssrf", params={"domain": "169.254.169.254"}) - - def test_ssrf_stack_trace(self): - assert self.r.status_code == 403 - validate_stack_traces(self.r) - - def setup_sqli_stack_trace(self): - self.r = weblog.get("/rasp/sqli", params={"user_id": "' OR 1 = 1 --"}) - - @missing_feature(library="dotnet") - def test_sqli_stack_trace(self): - assert self.r.status_code == 403 - validate_stack_traces(self.r) diff --git a/tests/appsec/rasp/utils.py b/tests/appsec/rasp/utils.py new file mode 100644 index 00000000000..1bffabb8966 --- /dev/null +++ b/tests/appsec/rasp/utils.py @@ -0,0 +1,180 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2021 Datadog, Inc. + +import json + +from utils import interfaces + + +def validate_span_tags(request, expected_meta=[], expected_metrics=[]): + """Validate RASP span tags are added when an event is generated""" + spans = [s for _, s in interfaces.library.get_root_spans(request=request)] + assert spans, "No spans to validate" + + for span in spans: + meta = span["meta"] + for m in expected_meta: + assert m in meta, f"missing span meta tag `{m}` in {meta}" + + metrics = span["metrics"] + for m in expected_metrics: + assert m in metrics, f"missing span metric tag `{m}` in {metrics}" + + +def validate_stack_traces(request): + events = list(interfaces.library.get_appsec_events(request=request)) + assert len(events) != 0, "No appsec event has been reported" + + for _, _, span, appsec_data in events: + assert "triggers" in appsec_data, "'triggers' not found in appsec_data" + + triggers = appsec_data["triggers"] + + # Find all stack IDs + stack_ids = [] + for event in triggers: + if "stack_id" in event: + stack_ids.append(event["stack_id"]) + + # The absence of stack IDs can be considered a bug + assert len(stack_ids) > 0, "no 'stack_id's present in 'triggers'" + + assert "meta_struct" in span, "'meta_struct' not found in span" + assert "_dd.stack" in span["meta_struct"], "'_dd.stack' not found in 'meta_struct'" + assert "exploit" in span["meta_struct"]["_dd.stack"], "'exploit' not found in '_dd.stack'" + + stack_traces = span["meta_struct"]["_dd.stack"]["exploit"] + assert stack_traces, "No stack traces to validate" + + for stack in stack_traces: + assert "language" in stack, "'language' not found in stack trace" + assert stack["language"] in ( + "php", + "python", + "nodejs", + "java", + "dotnet", + "go", + "ruby", + ), "unexpected language" + + # Ensure the stack ID corresponds to an appsec event + assert "id" in stack, "'id' not found in stack trace" + assert stack["id"] in stack_ids, "'id' doesn't correspond to an appsec event" + + assert "frames" in stack, "'frames' not found in stack trace" + assert len(stack["frames"]) <= 32, "stack trace above size limit (32 frames)" + + +def find_series(is_metrics: bool, namespace, metric): + request_type = "generate-metrics" if is_metrics else "distributions" + series = [] + for data in interfaces.library.get_telemetry_data(): + content = data["request"]["content"] + if content.get("request_type") != request_type: + continue + fallback_namespace = content["payload"].get("namespace") + for serie in content["payload"]["series"]: + computed_namespace = serie.get("namespace", fallback_namespace) + # Inject here the computed namespace considering the fallback. This simplifies later assertions. + serie["_computed_namespace"] = computed_namespace + if computed_namespace == namespace and serie["metric"] == metric: + series.append(serie) + return series + + +def validate_metric(name, type, metric): + return ( + metric.get("metric") == name + and metric.get("type") == "count" + and f"rule_type:{type}" in metric.get("tags", ()) + and any(s.startswith("waf_version:") for s in metric.get("tags", ())) + ) + + +def validate_metric_variant(name, type, variant, metric): + return ( + metric.get("metric") == name + and metric.get("type") == "count" + and f"rule_type:{type}" in metric.get("tags", ()) + and f"rule_variant:{variant}" in metric.get("tags", ()) + and any(s.startswith("waf_version:") for s in metric.get("tags", ())) + ) + + +def validate_metric_tag_version(tag_prefix, min_version, metric): + for tag in metric["tags"]: + if tag.startswith(tag_prefix + ":"): + version_str = tag.split(":")[1] + current_version = list(map(int, version_str.split("."))) + if current_version >= min_version: + return True + return False + + +def _load_file(file_path): + with open(file_path, "r") as f: + return json.load(f) + + +class RC_CONSTANTS: + CONFIG_ENABLED = ( + "datadog/2/ASM_FEATURES/asm_features_activation/config", + {"asm": {"enabled": True}}, + ) + BLOCK_405 = ( + "datadog/2/ASM/actions/config", + {"actions": [{"id": "block", "parameters": {"status_code": 405, "type": "json"}, "type": "block_request"}]}, + ) + + BLOCK_505 = ( + "datadog/2/ASM/actions/config", + {"actions": [{"id": "block", "parameters": {"status_code": 505, "type": "html"}, "type": "block_request"}]}, + ) + + BLOCK_REDIRECT = ( + "datadog/2/ASM/actions/config", + { + "actions": [ + { + "id": "block", + "parameters": {"location": "http://google.com", "status_code": 302}, + "type": "redirect_request", + } + ] + }, + ) + + RULES = ( + "datadog/2/ASM_DD/rules/config", + _load_file("./tests/appsec/rasp/rasp_ruleset.json"), + ) + + +class Base_Rules_Version: + """Test libddwaf version""" + + min_version = "1.13.3" + + def test_min_version(self): + """Checks data in waf.init metric to verify waf version""" + + min_version_array = list(map(int, self.min_version.split("."))) + series = find_series(True, "appsec", "waf.init") + assert series + assert any(validate_metric_tag_version("event_rules_version", min_version_array, s) for s in series) + + +class Base_WAF_Version: + """Test libddwaf version""" + + min_version = "1.20.1" + + def test_min_version(self): + """Checks data in waf.init metric to verify waf version""" + + min_version_array = list(map(int, self.min_version.split("."))) + series = find_series(True, "appsec", "waf.init") + assert series + assert any(validate_metric_tag_version("waf_version", min_version_array, s) for s in series) diff --git a/tests/appsec/rc_expected_requests_block_full_denylist_asm_data.json b/tests/appsec/rc_expected_requests_block_full_denylist_asm_data.json deleted file mode 100644 index 535b42a1506..00000000000 --- a/tests/appsec/rc_expected_requests_block_full_denylist_asm_data.json +++ /dev/null @@ -1,51 +0,0 @@ -[ - { - "client": { - "state": { - "root_version": 1, - "targets_version": 0, - "backend_client_state": "eyJmb28iOiAiYmFyIn0=" - } - }, - "test_description": "SUCCESS - No config. RFC about integrating with remote-config: https://docs.google.com/document/d/1u_G7TOr8wJX0dOM_zUDKuRJgxoJU_hVTd5SeaMucQUs" - }, - { - "client": { - "state": { - "root_version": 1, - "targets_version": 1, - "backend_client_state": "eyJmb28iOiAiYmFyIn0=" - } - }, - "test_description": "SUCCESS - No config. RFC about integrating with remote-config: https://docs.google.com/document/d/1u_G7TOr8wJX0dOM_zUDKuRJgxoJU_hVTd5SeaMucQUs" - }, - { - "client": { - "state": { - "root_version": 1, - "targets_version": 2, - "config_states": [ - { - "id": "ASM_DATA-base", - "version": 1, - "product": "ASM_DATA" - } - ], - "backend_client_state": "eyJmb28iOiAiYmFyIn0=" - } - }, - "cached_target_files": [ - { - "path": "datadog/2/ASM_DATA/ASM_DATA-base/config", - "length": 1319366, - "hashes": [ - { - "algorithm": "sha256", - "hash": "57c1fbf7685b05926b17e761ac13c3064e78bd303fa54bc5df598b49cfab01dd" - } - ] - } - ], - "test_description": "SUCCESS - Add 1250 users blocked and 1250 IPs blocked. RFC about integrating with remote-config: https://docs.google.com/document/d/1u_G7TOr8wJX0dOM_zUDKuRJgxoJU_hVTd5SeaMucQUs" - } -] \ No newline at end of file diff --git a/tests/appsec/test_PII.py b/tests/appsec/test_PII.py deleted file mode 100644 index 4336084818d..00000000000 --- a/tests/appsec/test_PII.py +++ /dev/null @@ -1,14 +0,0 @@ -# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. -# This product includes software developed at Datadog (https://www.datadoghq.com/). -# Copyright 2021 Datadog, Inc. - - -from utils import features - - -@features.appsec_scrubbing -class Test_Scrubbing: - """Appsec scrubs all sensitive data""" - - def test_main(self): - assert False, "Test not implemented" diff --git a/tests/appsec/test_alpha.py b/tests/appsec/test_alpha.py index 9df7aeebfa9..7cb6c5f9a96 100644 --- a/tests/appsec/test_alpha.py +++ b/tests/appsec/test_alpha.py @@ -5,16 +5,15 @@ from utils import context, weblog, interfaces, missing_feature, bug, features -@missing_feature(context.library == "ruby" and context.libddwaf_version is None) @features.threats_alpha_preview class Test_Basic: - """ Detect attacks on raw URI and headers with default rules """ + """Detect attacks on raw URI and headers with default rules""" def setup_uri(self): self.r_uri = weblog.get("/waf/0x5c0x2e0x2e0x2f") def test_uri(self): - """ Via server.request.uri.raw """ + """Via server.request.uri.raw""" # Note: we do not check the returned key_path nor rule_id for the alpha version interfaces.library.assert_waf_attack(self.r_uri, pattern="0x5c0x2e0x2e0x2f", address="server.request.uri.raw") @@ -22,12 +21,12 @@ def setup_headers(self): self.r_headers_1 = weblog.get("/waf/", headers={"MyHeader": "../../../secret.txt"}) self.r_headers_2 = weblog.get("/waf/", headers={"User-Agent": "Arachni/v1"}) - @bug(context.library == "python@1.1.0", reason="a PR was not included in the release") + @bug(context.library == "python@1.1.0", reason="APMRP-360") def test_headers(self): - """ Via server.request.headers.no_cookies """ + """Via server.request.headers.no_cookies""" # Note: we do not check the returned key_path nor rule_id for the alpha version address = "server.request.headers.no_cookies" - pattern = "/../" if context.appsec_rules_version < "1.2.6" else "../" + pattern = "../" interfaces.library.assert_waf_attack(self.r_headers_1, pattern=pattern, address=address) interfaces.library.assert_waf_attack(self.r_headers_2, pattern="Arachni/v", address=address) @@ -36,11 +35,11 @@ def setup_no_cookies(self): self.r_headers_2 = weblog.get("/waf/", cookies={"Cookie": "../../../secret.txt"}) def test_no_cookies(self): - """ Address server.request.headers.no_cookies should not include cookies. """ + """Address server.request.headers.no_cookies should not include cookies.""" # Relying on rule crs-930-110, test the following LFI attack is caught # on server.request.headers.no_cookies and then retry it with the cookies # to validate that cookies are properly excluded from server.request.headers.no_cookies. address = "server.request.headers.no_cookies" - pattern = "/../" if context.appsec_rules_version < "1.2.6" else "../" + pattern = "../" interfaces.library.assert_waf_attack(self.r_headers_1, pattern=pattern, address=address) interfaces.library.assert_no_appsec_event(self.r_headers_2) diff --git a/tests/appsec/test_asm_standalone.py b/tests/appsec/test_asm_standalone.py index 03604b7c672..8eb314753e5 100644 --- a/tests/appsec/test_asm_standalone.py +++ b/tests/appsec/test_asm_standalone.py @@ -1,27 +1,93 @@ import json -import re -from utils import weblog, interfaces, scenarios, features, rfc -from utils._context.header_tag_vars import * from requests.structures import CaseInsensitiveDict -# Python regexp that matches: -# "GET /requestdownstream" -# "GET /requestdownstream/" -# "GET requestdownstream" -# "GET requestdownstream/" -REQUESTDOWNSTREAM_RESOURCE_PATTERN = re.compile(r"GET /?requestdownstream/?") +from utils.telemetry_utils import TelemetryUtils +from utils import context, weblog, interfaces, scenarios, features, rfc, bug, flaky, missing_feature -@rfc("https://docs.google.com/document/d/12NBx-nD-IoQEMiCRnJXneq4Be7cbtSc6pJLOFUWTpNE/edit") -@features.appsec_standalone -@scenarios.appsec_standalone -class Test_AppSecStandalone_UpstreamPropagation: +class AsmStandalone_UpstreamPropagation_Base: """APM correctly propagates AppSec events in distributing tracing.""" # TODO downstream propagation - def setup_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_minus_1(self): + # This methods exist to test the 2 different ways of setting the tags in the tracers. + # In some tracers, the propagation tags are set in the first span of every trace chunk, + # while in others they are set in the local root span. (same for the sampling priority tag) + # This method test the first case and if it fails, it will test the second case. When both cases fail, the test will fail. + # + # first_trace is the first span of every trace chunk + # span is the local root span + # obj is the object where the tags are set (meta, metrics) + # expected_tags is a dict of tag name to value + # - The key is the tag name + # - The value can be None to assert that the tag is not present + # - The value can be a string to assert the value of the tag + # - The value can be a lambda function that will be used to assert the value of the tag (special case for _sampling_priority_v1) + # + + # Enpoint that triggers an ASM event and a downstream request + requestdownstreamUrl = "/requestdownstream" + + # Tested product + tested_product = None + + # Return a boolean indicating if the test passed + @staticmethod + def _assert_tags(first_trace, span, obj, expected_tags): + def _assert_tags_value(span, obj, expected_tags): + struct = span if obj is None else span[obj] + for tag, value in expected_tags.items(): + if value is None: + assert tag not in struct + else: + if tag == "_sampling_priority_v1": # special case, it's a lambda to check for a condition + assert value(struct[tag]) + else: + assert struct[tag] == value + + # Case 1: The tags are set on the first span of every trace chunk + try: + _assert_tags_value(first_trace, obj, expected_tags) + return True + except (KeyError, AssertionError) as e: + pass # should try the second case + + # Case 2: The tags are set on the local root span + try: + _assert_tags_value(span, obj, expected_tags) + return True + except (KeyError, AssertionError) as e: + return False + + @staticmethod + def assert_product_is_enabled(request, product): + product_enabled = False + tags = "_dd.iast.json" if product == "iast" else "_dd.appsec.json" + meta_struct_key = "iast" if product == "iast" else "appsec" + for data, trace, span in interfaces.library.get_spans(request=request): + # Check if the product is enabled in meta + meta = span["meta"] + if tags in meta: + product_enabled = True + break + # Check if the product is enabled in meta_struct + meta_struct = span["meta_struct"] + if meta_struct and meta_struct.get(meta_struct_key): + product_enabled = True + break + assert product_enabled, f"{product} is not available" + + def setup_product_is_enabled(self): + headers = {} + if self.tested_product == "appsec": + headers = { + "User-Agent": "Arachni/v1", # attack if APPSEC enabled + } + self.check_r = weblog.get(self.requestdownstreamUrl, headers=headers) + + def setup_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_minus_1(self): + self.setup_product_is_enabled() trace_id = 1212121212121212121 parent_id = 34343434 self.r = weblog.get( @@ -35,21 +101,23 @@ def setup_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_minus_1(s }, ) - def test_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_minus_1(self): + def test_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_minus_1(self): + self.assert_product_is_enabled(self.check_r, self.tested_product) spans_checked = 0 - for data, _, span in interfaces.library.get_spans(request=self.r): - if not REQUESTDOWNSTREAM_RESOURCE_PATTERN.search(span["resource"]): - continue + tested_meta = {"_dd.p.appsec": None, "_dd.p.other": "1"} + tested_metrics = {"_sampling_priority_v1": lambda x: x < 2} - assert span["metrics"]["_sampling_priority_v1"] < 2 - assert span["metrics"]["_dd.apm.enabled"] == 0 - assert "_dd.p.appsec" not in span["meta"] - assert "_dd.p.other" in span["meta"] + for data, trace, span in interfaces.library.get_spans(request=self.r): + assert self._assert_tags(trace[0], span, "meta", tested_meta) + assert self._assert_tags(trace[0], span, "metrics", tested_metrics) + + assert span["metrics"]["_dd.apm.enabled"] == 0 # if key missing -> APPSEC-55222 assert span["trace_id"] == 1212121212121212121 + assert trace[0]["trace_id"] == 1212121212121212121 # Some tracers use true while others use yes assert any( - ["Datadog-Client-Computed-Stats", trueish,] in data["request"]["headers"] for trueish in ["yes", "true"] + ["Datadog-Client-Computed-Stats", trueish] in data["request"]["headers"] for trueish in ["yes", "true"] ) spans_checked += 1 @@ -62,11 +130,12 @@ def test_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_minus_1(se assert "X-Datadog-Sampling-Priority" not in downstream_headers assert "X-Datadog-Trace-Id" not in downstream_headers - def setup_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_0(self): + def setup_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_0(self): + self.setup_product_is_enabled() trace_id = 1212121212121212121 parent_id = 34343434 self.r = weblog.get( - "/requestdownstream/", + "/requestdownstream", headers={ "x-datadog-trace-id": str(trace_id), "x-datadog-parent-id": str(parent_id), @@ -76,21 +145,23 @@ def setup_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_0(self): }, ) - def test_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_0(self): + def test_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_0(self): + self.assert_product_is_enabled(self.check_r, self.tested_product) spans_checked = 0 - for data, _, span in interfaces.library.get_spans(request=self.r): - if not REQUESTDOWNSTREAM_RESOURCE_PATTERN.search(span["resource"]): - continue + tested_meta = {"_dd.p.appsec": None, "_dd.p.other": "1"} + tested_metrics = {"_sampling_priority_v1": lambda x: x < 2} - assert span["metrics"]["_sampling_priority_v1"] < 2 - assert span["metrics"]["_dd.apm.enabled"] == 0 - assert "_dd.p.appsec" not in span["meta"] - assert "_dd.p.other" in span["meta"] + for data, trace, span in interfaces.library.get_spans(request=self.r): + assert self._assert_tags(trace[0], span, "meta", tested_meta) + assert self._assert_tags(trace[0], span, "metrics", tested_metrics) + + assert span["metrics"]["_dd.apm.enabled"] == 0 # if key missing -> APPSEC-55222 assert span["trace_id"] == 1212121212121212121 + assert trace[0]["trace_id"] == 1212121212121212121 # Some tracers use true while others use yes assert any( - ["Datadog-Client-Computed-Stats", trueish,] in data["request"]["headers"] for trueish in ["yes", "true"] + ["Datadog-Client-Computed-Stats", trueish] in data["request"]["headers"] for trueish in ["yes", "true"] ) spans_checked += 1 @@ -103,11 +174,12 @@ def test_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_0(self): assert "X-Datadog-Sampling-Priority" not in downstream_headers assert "X-Datadog-Trace-Id" not in downstream_headers - def setup_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_1(self): + def setup_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_1(self): + self.setup_product_is_enabled() trace_id = 1212121212121212121 parent_id = 34343434 self.r = weblog.get( - "/requestdownstream/", + "/requestdownstream", headers={ "x-datadog-trace-id": str(trace_id), "x-datadog-parent-id": str(parent_id), @@ -117,21 +189,23 @@ def setup_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_1(self): }, ) - def test_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_1(self): + def test_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_1(self): + self.assert_product_is_enabled(self.check_r, self.tested_product) spans_checked = 0 - for data, _, span in interfaces.library.get_spans(request=self.r): - if not REQUESTDOWNSTREAM_RESOURCE_PATTERN.search(span["resource"]): - continue + tested_meta = {"_dd.p.appsec": None, "_dd.p.other": "1"} + tested_metrics = {"_sampling_priority_v1": lambda x: x < 2} - assert span["metrics"]["_sampling_priority_v1"] < 2 - assert span["metrics"]["_dd.apm.enabled"] == 0 - assert "_dd.p.appsec" not in span["meta"] - assert "_dd.p.other" in span["meta"] + for data, trace, span in interfaces.library.get_spans(request=self.r): + assert self._assert_tags(trace[0], span, "meta", tested_meta) + assert self._assert_tags(trace[0], span, "metrics", tested_metrics) + + assert span["metrics"]["_dd.apm.enabled"] == 0 # if key missing -> APPSEC-55222 assert span["trace_id"] == 1212121212121212121 + assert trace[0]["trace_id"] == 1212121212121212121 # Some tracers use true while others use yes assert any( - ["Datadog-Client-Computed-Stats", trueish,] in data["request"]["headers"] for trueish in ["yes", "true"] + ["Datadog-Client-Computed-Stats", trueish] in data["request"]["headers"] for trueish in ["yes", "true"] ) spans_checked += 1 @@ -144,11 +218,12 @@ def test_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_1(self): assert "X-Datadog-Sampling-Priority" not in downstream_headers assert "X-Datadog-Trace-Id" not in downstream_headers - def setup_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_2(self): + def setup_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_2(self): + self.setup_product_is_enabled() trace_id = 1212121212121212121 parent_id = 34343434 self.r = weblog.get( - "/requestdownstream/", + "/requestdownstream", headers={ "x-datadog-trace-id": str(trace_id), "x-datadog-parent-id": str(parent_id), @@ -158,21 +233,23 @@ def setup_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_2(self): }, ) - def test_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_2(self): + def test_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_2(self): + self.assert_product_is_enabled(self.check_r, self.tested_product) spans_checked = 0 - for data, _, span in interfaces.library.get_spans(request=self.r): - if not REQUESTDOWNSTREAM_RESOURCE_PATTERN.search(span["resource"]): - continue + tested_meta = {"_dd.p.appsec": None, "_dd.p.other": "1"} + tested_metrics = {"_sampling_priority_v1": lambda x: x < 2} - assert span["metrics"]["_sampling_priority_v1"] < 2 - assert span["metrics"]["_dd.apm.enabled"] == 0 - assert "_dd.p.appsec" not in span["meta"] - assert "_dd.p.other" in span["meta"] + for data, trace, span in interfaces.library.get_spans(request=self.r): + assert self._assert_tags(trace[0], span, "meta", tested_meta) + assert self._assert_tags(trace[0], span, "metrics", tested_metrics) + + assert span["metrics"]["_dd.apm.enabled"] == 0 # if key missing -> APPSEC-55222 assert span["trace_id"] == 1212121212121212121 + assert trace[0]["trace_id"] == 1212121212121212121 # Some tracers use true while others use yes assert any( - ["Datadog-Client-Computed-Stats", trueish,] in data["request"]["headers"] for trueish in ["yes", "true"] + ["Datadog-Client-Computed-Stats", trueish] in data["request"]["headers"] for trueish in ["yes", "true"] ) spans_checked += 1 @@ -185,35 +262,37 @@ def test_no_appsec_upstream__no_attack__is_kept_with_priority_1__from_2(self): assert "X-Datadog-Sampling-Priority" not in downstream_headers assert "X-Datadog-Trace-Id" not in downstream_headers - def setup_no_upstream_appsec_propagation__with_attack__is_kept_with_priority_2__from_minus_1(self): + def setup_no_upstream_appsec_propagation__with_asm_event__is_kept_with_priority_2__from_minus_1(self): trace_id = 1212121212121212121 parent_id = 34343434 self.r = weblog.get( - "/requestdownstream", + self.requestdownstreamUrl, headers={ "x-datadog-trace-id": str(trace_id), "x-datadog-parent-id": str(parent_id), "x-datadog-origin": "rum", "x-datadog-sampling-priority": "-1", "x-datadog-tags": "_dd.p.other=1", - "User-Agent": "Arachni/v1", + "User-Agent": "Arachni/v1", # attack if APPSEC enabled }, ) - def test_no_upstream_appsec_propagation__with_attack__is_kept_with_priority_2__from_minus_1(self): + def test_no_upstream_appsec_propagation__with_asm_event__is_kept_with_priority_2__from_minus_1(self): spans_checked = 0 - for data, _, span in interfaces.library.get_spans(request=self.r): - if not REQUESTDOWNSTREAM_RESOURCE_PATTERN.search(span["resource"]): - continue + tested_meta = {"_dd.p.appsec": "1"} + tested_metrics = {"_sampling_priority_v1": lambda x: x == 2} - assert span["metrics"]["_sampling_priority_v1"] == 2 - assert span["metrics"]["_dd.apm.enabled"] == 0 - assert span["meta"]["_dd.p.appsec"] == "1" + for data, trace, span in interfaces.library.get_spans(request=self.r): + assert self._assert_tags(trace[0], span, "meta", tested_meta) + assert self._assert_tags(trace[0], span, "metrics", tested_metrics) + + assert span["metrics"]["_dd.apm.enabled"] == 0 # if key missing -> APPSEC-55222 assert span["trace_id"] == 1212121212121212121 + assert trace[0]["trace_id"] == 1212121212121212121 # Some tracers use true while others use yes assert any( - ["Datadog-Client-Computed-Stats", trueish,] in data["request"]["headers"] for trueish in ["yes", "true"] + ["Datadog-Client-Computed-Stats", trueish] in data["request"]["headers"] for trueish in ["yes", "true"] ) spans_checked += 1 @@ -226,35 +305,38 @@ def test_no_upstream_appsec_propagation__with_attack__is_kept_with_priority_2__f assert downstream_headers["X-Datadog-Sampling-Priority"] == "2" assert downstream_headers["X-Datadog-Trace-Id"] == "1212121212121212121" - def setup_no_upstream_appsec_propagation__with_attack__is_kept_with_priority_2__from_0(self): + def setup_no_upstream_appsec_propagation__with_asm_event__is_kept_with_priority_2__from_0(self): trace_id = 1212121212121212121 parent_id = 34343434 self.r = weblog.get( - "/requestdownstream/", + self.requestdownstreamUrl, headers={ "x-datadog-trace-id": str(trace_id), "x-datadog-parent-id": str(parent_id), "x-datadog-origin": "rum", "x-datadog-sampling-priority": "0", "x-datadog-tags": "_dd.p.other=1", - "User-Agent": "Arachni/v1", + "User-Agent": "Arachni/v1", # attack if APPSEC enabled }, ) - def test_no_upstream_appsec_propagation__with_attack__is_kept_with_priority_2__from_0(self): + @flaky(library="python", reason="APPSEC-55222") # _dd.apm.enabled missing in metrics + def test_no_upstream_appsec_propagation__with_asm_event__is_kept_with_priority_2__from_0(self): spans_checked = 0 - for data, _, span in interfaces.library.get_spans(request=self.r): - if not REQUESTDOWNSTREAM_RESOURCE_PATTERN.search(span["resource"]): - continue + tested_meta = {"_dd.p.appsec": "1"} + tested_metrics = {"_sampling_priority_v1": lambda x: x == 2} + + for data, trace, span in interfaces.library.get_spans(request=self.r): + assert self._assert_tags(trace[0], span, "meta", tested_meta) + assert self._assert_tags(trace[0], span, "metrics", tested_metrics) - assert span["metrics"]["_sampling_priority_v1"] == 2 assert span["metrics"]["_dd.apm.enabled"] == 0 - assert span["meta"]["_dd.p.appsec"] == "1" assert span["trace_id"] == 1212121212121212121 + assert trace[0]["trace_id"] == 1212121212121212121 # Some tracers use true while others use yes assert any( - ["Datadog-Client-Computed-Stats", trueish,] in data["request"]["headers"] for trueish in ["yes", "true"] + ["Datadog-Client-Computed-Stats", trueish] in data["request"]["headers"] for trueish in ["yes", "true"] ) spans_checked += 1 @@ -267,11 +349,12 @@ def test_no_upstream_appsec_propagation__with_attack__is_kept_with_priority_2__f assert downstream_headers["X-Datadog-Sampling-Priority"] == "2" assert downstream_headers["X-Datadog-Trace-Id"] == "1212121212121212121" - def setup_upstream_appsec_propagation__no_attack__is_propagated_as_is__being_0(self): + def setup_upstream_appsec_propagation__no_asm_event__is_propagated_as_is__being_0(self): + self.setup_product_is_enabled() trace_id = 1212121212121212121 parent_id = 34343434 self.r = weblog.get( - "/requestdownstream/", + "/requestdownstream", headers={ "x-datadog-trace-id": str(trace_id), "x-datadog-parent-id": str(parent_id), @@ -281,20 +364,23 @@ def setup_upstream_appsec_propagation__no_attack__is_propagated_as_is__being_0(s }, ) - def test_upstream_appsec_propagation__no_attack__is_propagated_as_is__being_0(self): + def test_upstream_appsec_propagation__no_asm_event__is_propagated_as_is__being_0(self): + self.assert_product_is_enabled(self.check_r, self.tested_product) spans_checked = 0 - for data, _, span in interfaces.library.get_spans(request=self.r): - if not REQUESTDOWNSTREAM_RESOURCE_PATTERN.search(span["resource"]): - continue + tested_meta = {"_dd.p.appsec": "1"} + tested_metrics = {"_sampling_priority_v1": lambda x: x in [0, 2]} - assert span["metrics"]["_sampling_priority_v1"] == 2 - assert span["metrics"]["_dd.apm.enabled"] == 0 - assert span["meta"]["_dd.p.appsec"] == "1" + for data, trace, span in interfaces.library.get_spans(request=self.r): + assert self._assert_tags(trace[0], span, "meta", tested_meta) + assert self._assert_tags(trace[0], span, "metrics", tested_metrics) + + assert span["metrics"]["_dd.apm.enabled"] == 0 # if key missing -> APPSEC-55222 assert span["trace_id"] == 1212121212121212121 + assert trace[0]["trace_id"] == 1212121212121212121 # Some tracers use true while others use yes assert any( - ["Datadog-Client-Computed-Stats", trueish,] in data["request"]["headers"] for trueish in ["yes", "true"] + ["Datadog-Client-Computed-Stats", trueish] in data["request"]["headers"] for trueish in ["yes", "true"] ) spans_checked += 1 @@ -303,14 +389,15 @@ def test_upstream_appsec_propagation__no_attack__is_propagated_as_is__being_0(se assert downstream_headers["X-Datadog-Origin"] == "rum" assert downstream_headers["X-Datadog-Parent-Id"] != "34343434" assert "_dd.p.appsec=1" in downstream_headers["X-Datadog-Tags"] - assert downstream_headers["X-Datadog-Sampling-Priority"] == "2" + assert downstream_headers["X-Datadog-Sampling-Priority"] in ["0", "2"] assert downstream_headers["X-Datadog-Trace-Id"] == "1212121212121212121" - def setup_upstream_appsec_propagation__no_attack__is_propagated_as_is__being_1(self): + def setup_upstream_appsec_propagation__no_asm_event__is_propagated_as_is__being_1(self): + self.setup_product_is_enabled() trace_id = 1212121212121212121 parent_id = 34343434 self.r = weblog.get( - "/requestdownstream/", + "/requestdownstream", headers={ "x-datadog-trace-id": str(trace_id), "x-datadog-parent-id": str(parent_id), @@ -320,20 +407,23 @@ def setup_upstream_appsec_propagation__no_attack__is_propagated_as_is__being_1(s }, ) - def test_upstream_appsec_propagation__no_attack__is_propagated_as_is__being_1(self): + def test_upstream_appsec_propagation__no_asm_event__is_propagated_as_is__being_1(self): + self.assert_product_is_enabled(self.check_r, self.tested_product) spans_checked = 0 - for data, _, span in interfaces.library.get_spans(request=self.r): - if not REQUESTDOWNSTREAM_RESOURCE_PATTERN.search(span["resource"]): - continue + tested_meta = {"_dd.p.appsec": "1"} + tested_metrics = {"_sampling_priority_v1": lambda x: x in [1, 2]} - assert span["metrics"]["_sampling_priority_v1"] == 2 - assert span["metrics"]["_dd.apm.enabled"] == 0 - assert span["meta"]["_dd.p.appsec"] == "1" + for data, trace, span in interfaces.library.get_spans(request=self.r): + assert self._assert_tags(trace[0], span, "meta", tested_meta) + assert self._assert_tags(trace[0], span, "metrics", tested_metrics) + + assert span["metrics"]["_dd.apm.enabled"] == 0 # if key missing -> APPSEC-55222 assert span["trace_id"] == 1212121212121212121 + assert trace[0]["trace_id"] == 1212121212121212121 # Some tracers use true while others use yes assert any( - ["Datadog-Client-Computed-Stats", trueish,] in data["request"]["headers"] for trueish in ["yes", "true"] + ["Datadog-Client-Computed-Stats", trueish] in data["request"]["headers"] for trueish in ["yes", "true"] ) spans_checked += 1 @@ -342,10 +432,11 @@ def test_upstream_appsec_propagation__no_attack__is_propagated_as_is__being_1(se assert downstream_headers["X-Datadog-Origin"] == "rum" assert downstream_headers["X-Datadog-Parent-Id"] != "34343434" assert "_dd.p.appsec=1" in downstream_headers["X-Datadog-Tags"] - assert downstream_headers["X-Datadog-Sampling-Priority"] == "2" + assert downstream_headers["X-Datadog-Sampling-Priority"] in ["1", "2"] assert downstream_headers["X-Datadog-Trace-Id"] == "1212121212121212121" - def setup_upstream_appsec_propagation__no_attack__is_propagated_as_is__being_2(self): + def setup_upstream_appsec_propagation__no_asm_event__is_propagated_as_is__being_2(self): + self.setup_product_is_enabled() trace_id = 1212121212121212121 parent_id = 34343434 self.r = weblog.get( @@ -359,20 +450,23 @@ def setup_upstream_appsec_propagation__no_attack__is_propagated_as_is__being_2(s }, ) - def test_upstream_appsec_propagation__no_attack__is_propagated_as_is__being_2(self): + def test_upstream_appsec_propagation__no_asm_event__is_propagated_as_is__being_2(self): + self.assert_product_is_enabled(self.check_r, self.tested_product) spans_checked = 0 - for data, _, span in interfaces.library.get_spans(request=self.r): - if not REQUESTDOWNSTREAM_RESOURCE_PATTERN.search(span["resource"]): - continue + tested_meta = {"_dd.p.appsec": "1"} + tested_metrics = {"_sampling_priority_v1": lambda x: x == 2} - assert span["metrics"]["_sampling_priority_v1"] == 2 - assert span["metrics"]["_dd.apm.enabled"] == 0 - assert span["meta"]["_dd.p.appsec"] == "1" + for data, trace, span in interfaces.library.get_spans(request=self.r): + assert self._assert_tags(trace[0], span, "meta", tested_meta) + assert self._assert_tags(trace[0], span, "metrics", tested_metrics) + + assert span["metrics"]["_dd.apm.enabled"] == 0 # if key missing -> APPSEC-55222 assert span["trace_id"] == 1212121212121212121 + assert trace[0]["trace_id"] == 1212121212121212121 # Some tracers use true while others use yes assert any( - ["Datadog-Client-Computed-Stats", trueish,] in data["request"]["headers"] for trueish in ["yes", "true"] + ["Datadog-Client-Computed-Stats", trueish] in data["request"]["headers"] for trueish in ["yes", "true"] ) spans_checked += 1 @@ -384,34 +478,36 @@ def test_upstream_appsec_propagation__no_attack__is_propagated_as_is__being_2(se assert downstream_headers["X-Datadog-Sampling-Priority"] == "2" assert downstream_headers["X-Datadog-Trace-Id"] == "1212121212121212121" - def setup_any_upstream_propagation__with_attack__raises_priority_to_2__from_minus_1(self): + def setup_any_upstream_propagation__with_asm_event__raises_priority_to_2__from_minus_1(self): trace_id = 1212121212121212121 parent_id = 34343434 self.r = weblog.get( - "/requestdownstream", + self.requestdownstreamUrl, headers={ "x-datadog-trace-id": str(trace_id), "x-datadog-parent-id": str(parent_id), "x-datadog-origin": "rum", "x-datadog-sampling-priority": "-1", - "User-Agent": "Arachni/v1", + "User-Agent": "Arachni/v1", # attack if APPSEC enabled }, ) - def test_any_upstream_propagation__with_attack__raises_priority_to_2__from_minus_1(self): + def test_any_upstream_propagation__with_asm_event__raises_priority_to_2__from_minus_1(self): spans_checked = 0 - for data, _, span in interfaces.library.get_spans(request=self.r): - if not REQUESTDOWNSTREAM_RESOURCE_PATTERN.search(span["resource"]): - continue + tested_meta = {"_dd.p.appsec": "1"} + tested_metrics = {"_sampling_priority_v1": lambda x: x == 2} - assert span["metrics"]["_sampling_priority_v1"] == 2 - assert span["metrics"]["_dd.apm.enabled"] == 0 - assert span["meta"]["_dd.p.appsec"] == "1" + for data, trace, span in interfaces.library.get_spans(request=self.r): + assert self._assert_tags(trace[0], span, "meta", tested_meta) + assert self._assert_tags(trace[0], span, "metrics", tested_metrics) + + assert span["metrics"]["_dd.apm.enabled"] == 0 # if key missing -> APPSEC-55222 assert span["trace_id"] == 1212121212121212121 + assert trace[0]["trace_id"] == 1212121212121212121 # Some tracers use true while others use yes assert any( - ["Datadog-Client-Computed-Stats", trueish,] in data["request"]["headers"] for trueish in ["yes", "true"] + ["Datadog-Client-Computed-Stats", trueish] in data["request"]["headers"] for trueish in ["yes", "true"] ) spans_checked += 1 @@ -423,11 +519,11 @@ def test_any_upstream_propagation__with_attack__raises_priority_to_2__from_minus assert downstream_headers["X-Datadog-Sampling-Priority"] == "2" assert downstream_headers["X-Datadog-Trace-Id"] == "1212121212121212121" - def setup_any_upstream_propagation__with_attack__raises_priority_to_2__from_0(self): + def setup_any_upstream_propagation__with_asm_event__raises_priority_to_2__from_0(self): trace_id = 1212121212121212121 parent_id = 34343434 self.r = weblog.get( - "/requestdownstream/", + self.requestdownstreamUrl, headers={ "x-datadog-trace-id": str(trace_id), "x-datadog-parent-id": str(parent_id), @@ -437,20 +533,22 @@ def setup_any_upstream_propagation__with_attack__raises_priority_to_2__from_0(se }, ) - def test_any_upstream_propagation__with_attack__raises_priority_to_2__from_0(self): + def test_any_upstream_propagation__with_asm_event__raises_priority_to_2__from_0(self): spans_checked = 0 - for data, _, span in interfaces.library.get_spans(request=self.r): - if not REQUESTDOWNSTREAM_RESOURCE_PATTERN.search(span["resource"]): - continue + tested_meta = {"_dd.p.appsec": "1"} + tested_metrics = {"_sampling_priority_v1": lambda x: x == 2} - assert span["metrics"]["_sampling_priority_v1"] == 2 - assert span["metrics"]["_dd.apm.enabled"] == 0 - assert span["meta"]["_dd.p.appsec"] == "1" + for data, trace, span in interfaces.library.get_spans(request=self.r): + assert self._assert_tags(trace[0], span, "meta", tested_meta) + assert self._assert_tags(trace[0], span, "metrics", tested_metrics) + + assert span["metrics"]["_dd.apm.enabled"] == 0 # if key missing -> APPSEC-55222 assert span["trace_id"] == 1212121212121212121 + assert trace[0]["trace_id"] == 1212121212121212121 # Some tracers use true while others use yes assert any( - ["Datadog-Client-Computed-Stats", trueish,] in data["request"]["headers"] for trueish in ["yes", "true"] + ["Datadog-Client-Computed-Stats", trueish] in data["request"]["headers"] for trueish in ["yes", "true"] ) spans_checked += 1 @@ -462,34 +560,36 @@ def test_any_upstream_propagation__with_attack__raises_priority_to_2__from_0(sel assert downstream_headers["X-Datadog-Sampling-Priority"] == "2" assert downstream_headers["X-Datadog-Trace-Id"] == "1212121212121212121" - def setup_any_upstream_propagation__with_attack__raises_priority_to_2__from_1(self): + def setup_any_upstream_propagation__with_asm_event__raises_priority_to_2__from_1(self): trace_id = 1212121212121212121 parent_id = 34343434 self.r = weblog.get( - "/requestdownstream/", + self.requestdownstreamUrl, headers={ "x-datadog-trace-id": str(trace_id), "x-datadog-parent-id": str(parent_id), "x-datadog-origin": "rum", "x-datadog-sampling-priority": "1", - "User-Agent": "Arachni/v1", + "User-Agent": "Arachni/v1", # attack if APPSEC enabled }, ) - def test_any_upstream_propagation__with_attack__raises_priority_to_2__from_1(self): + def test_any_upstream_propagation__with_asm_event__raises_priority_to_2__from_1(self): spans_checked = 0 - for data, _, span in interfaces.library.get_spans(request=self.r): - if not REQUESTDOWNSTREAM_RESOURCE_PATTERN.search(span["resource"]): - continue + tested_meta = {"_dd.p.appsec": "1"} + tested_metrics = {"_sampling_priority_v1": lambda x: x == 2} - assert span["metrics"]["_sampling_priority_v1"] == 2 - assert span["metrics"]["_dd.apm.enabled"] == 0 - assert span["meta"]["_dd.p.appsec"] == "1" + for data, trace, span in interfaces.library.get_spans(request=self.r): + assert self._assert_tags(trace[0], span, "meta", tested_meta) + assert self._assert_tags(trace[0], span, "metrics", tested_metrics) + + assert span["metrics"]["_dd.apm.enabled"] == 0 # if key missing -> APPSEC-55222 assert span["trace_id"] == 1212121212121212121 + assert trace[0]["trace_id"] == 1212121212121212121 # Some tracers use true while others use yes assert any( - ["Datadog-Client-Computed-Stats", trueish,] in data["request"]["headers"] for trueish in ["yes", "true"] + ["Datadog-Client-Computed-Stats", trueish] in data["request"]["headers"] for trueish in ["yes", "true"] ) spans_checked += 1 @@ -500,3 +600,135 @@ def test_any_upstream_propagation__with_attack__raises_priority_to_2__from_1(sel assert "_dd.p.appsec=1" in downstream_headers["X-Datadog-Tags"] assert downstream_headers["X-Datadog-Sampling-Priority"] == "2" assert downstream_headers["X-Datadog-Trace-Id"] == "1212121212121212121" + + +@rfc("https://docs.google.com/document/d/12NBx-nD-IoQEMiCRnJXneq4Be7cbtSc6pJLOFUWTpNE/edit") +@features.appsec_standalone +@scenarios.appsec_standalone +@flaky(context.library >= "python@2.18.0+dev", reason="APPSEC-56142") +class Test_AppSecStandalone_UpstreamPropagation(AsmStandalone_UpstreamPropagation_Base): + """APPSEC correctly propagates AppSec events in distributing tracing.""" + + requestdownstreamUrl = "/requestdownstream" + + tested_product = "appsec" + + @bug(library="java", weblog_variant="akka-http", reason="APPSEC-55001") + @bug(library="java", weblog_variant="jersey-grizzly2", reason="APPSEC-55001") + @bug(library="java", weblog_variant="play", reason="APPSEC-55001") + def test_no_upstream_appsec_propagation__with_asm_event__is_kept_with_priority_2__from_minus_1(self): + super().test_no_upstream_appsec_propagation__with_asm_event__is_kept_with_priority_2__from_minus_1() + + @bug(library="java", weblog_variant="akka-http", reason="APPSEC-55001") + @bug(library="java", weblog_variant="jersey-grizzly2", reason="APPSEC-55001") + @bug(library="java", weblog_variant="play", reason="APPSEC-55001") + def test_no_upstream_appsec_propagation__with_asm_event__is_kept_with_priority_2__from_0(self): + super().test_no_upstream_appsec_propagation__with_asm_event__is_kept_with_priority_2__from_0() + + @bug(library="java", weblog_variant="akka-http", reason="APPSEC-55001") + @bug(library="java", weblog_variant="jersey-grizzly2", reason="APPSEC-55001") + @bug(library="java", weblog_variant="play", reason="APPSEC-55001") + def test_any_upstream_propagation__with_asm_event__raises_priority_to_2__from_minus_1(self): + super().test_any_upstream_propagation__with_asm_event__raises_priority_to_2__from_minus_1() + + @bug(library="java", weblog_variant="akka-http", reason="APPSEC-55001") + @bug(library="java", weblog_variant="jersey-grizzly2", reason="APPSEC-55001") + @bug(library="java", weblog_variant="play", reason="APPSEC-55001") + def test_any_upstream_propagation__with_asm_event__raises_priority_to_2__from_0(self): + super().test_any_upstream_propagation__with_asm_event__raises_priority_to_2__from_0() + + @bug(library="java", weblog_variant="akka-http", reason="APPSEC-55001") + @bug(library="java", weblog_variant="jersey-grizzly2", reason="APPSEC-55001") + @bug(library="java", weblog_variant="play", reason="APPSEC-55001") + def test_any_upstream_propagation__with_asm_event__raises_priority_to_2__from_1(self): + super().test_any_upstream_propagation__with_asm_event__raises_priority_to_2__from_1() + + +@rfc("https://docs.google.com/document/d/12NBx-nD-IoQEMiCRnJXneq4Be7cbtSc6pJLOFUWTpNE/edit") +@features.iast_standalone +@scenarios.iast_standalone +class Test_IastStandalone_UpstreamPropagation(AsmStandalone_UpstreamPropagation_Base): + """IAST correctly propagates AppSec events in distributing tracing.""" + + requestdownstreamUrl = "/vulnerablerequestdownstream" + + tested_product = "iast" + + @bug(library="java", weblog_variant="play", reason="APPSEC-55552") + def test_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_minus_1(self): + super().test_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_minus_1() + + @bug(library="java", weblog_variant="play", reason="APPSEC-55552") + def test_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_0(self): + super().test_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_0() + + @bug(library="java", weblog_variant="play", reason="APPSEC-55552") + def test_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_1(self): + super().test_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_1() + + @bug(library="java", weblog_variant="play", reason="APPSEC-55552") + def test_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_2(self): + super().test_no_appsec_upstream__no_asm_event__is_kept_with_priority_1__from_2() + + +@rfc("https://docs.google.com/document/d/12NBx-nD-IoQEMiCRnJXneq4Be7cbtSc6pJLOFUWTpNE/edit") +@features.sca_standalone +@scenarios.sca_standalone +class Test_SCAStandalone_Telemetry: + """Tracer correctly propagates SCA telemetry in distributing tracing.""" + + def assert_standalone_is_enabled(self, request): + # test standalone is enabled and dropping traces + for data, _trace, span in interfaces.library.get_spans(request): + assert span["metrics"]["_sampling_priority_v1"] <= 0 + assert span["metrics"]["_dd.apm.enabled"] == 0 + + def setup_telemetry_sca_enabled_propagated(self): + self.r = weblog.get("/") + + def test_telemetry_sca_enabled_propagated(self): + self.assert_standalone_is_enabled(self.r) + + for data in interfaces.library.get_telemetry_data(): + content = data["request"]["content"] + if content.get("request_type") != "app-started": + continue + configuration = content["payload"]["configuration"] + + configuration_by_name = {item["name"]: item for item in configuration} + + assert configuration_by_name + + DD_APPSEC_SCA_ENABLED = TelemetryUtils.get_dd_appsec_sca_enabled_str(context.library) + + cfg_appsec_enabled = configuration_by_name.get(DD_APPSEC_SCA_ENABLED) + assert cfg_appsec_enabled is not None, "Missing telemetry config item for '{}'".format(DD_APPSEC_SCA_ENABLED) + + outcome_value = True + if context.library == "java": + outcome_value = str(outcome_value).lower() + assert cfg_appsec_enabled.get("value") == outcome_value + + def setup_app_dependencies_loaded(self): + self.r = weblog.get("/load_dependency") + + @missing_feature(context.library == "nodejs" and context.weblog_variant == "nextjs") + def test_app_dependencies_loaded(self): + self.assert_standalone_is_enabled(self.r) + + seen_loaded_dependencies = TelemetryUtils.get_loaded_dependency(context.library.library) + + for data in interfaces.library.get_telemetry_data(): + content = data["request"]["content"] + if content.get("request_type") != "app-dependencies-loaded": + continue + + for dependency in content["payload"]["dependencies"]: + dependency_id = dependency["name"] # +dependency["version"] + + if dependency_id in seen_loaded_dependencies: + seen_loaded_dependencies[dependency_id] = True + + for dependency, seen in seen_loaded_dependencies.items(): + if not seen: + raise Exception(dependency + " not received in app-dependencies-loaded message") diff --git a/tests/appsec/test_automated_login_events.py b/tests/appsec/test_automated_login_events.py index f30cf3dbe5c..bd4bead6862 100644 --- a/tests/appsec/test_automated_login_events.py +++ b/tests/appsec/test_automated_login_events.py @@ -2,24 +2,72 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2022 Datadog, Inc. -from utils import ( - weblog, - interfaces, - context, - missing_feature, - scenarios, - rfc, - bug, - features, - irrelevant, - remote_config as rc, -) +from utils import bug +from utils import context +from utils import features +from utils import interfaces +from utils import irrelevant +from utils import missing_feature +from utils import remote_config as rc +from utils import rfc +from utils import scenarios +from utils import weblog +from utils.dd_constants import Capabilities + + +def login_data(context, username, password): + """In Rails the parameters are group by scope. In the case of the test the scope is user. + The syntax to group parameters in a POST request is scope[parameter] + """ + username_key = "user[username]" if "rails" in context.weblog_variant else "username" + password_key = "user[password]" if "rails" in context.weblog_variant else "password" + return {username_key: username, password_key: password} + + +USER = "test" +UUID_USER = "testuuid" +PASSWORD = "1234" +INVALID_USER = "invalidUser" +NEW_USER = "testnew" +USER_HASH = "anon_5f31ffaf95946d2dc703ddc96a100de5" +USERNAME_HASH = "anon_9f86d081884c7d659a2feaa0c55ad015" +INVALID_USER_HASH = "anon_2141e3bee69f7de45b4f1d8d1f29258a" +NEW_USER_HASH = "anon_6724757d2d9a8113ec9ec57003bf7b3e" +NEW_USERNAME_HASH = "anon_3de740d12dc67b5b1db699424c130847" + +BASIC_AUTH_USER_HEADER = "Basic dGVzdDoxMjM0" # base64(test:1234) +BASIC_AUTH_USER_UUID_HEADER = "Basic dGVzdHV1aWQ6MTIzNA==" # base64(testuuid:1234) +BASIC_AUTH_INVALID_USER_HEADER = "Basic aW52YWxpZFVzZXI6MTIzNA==" # base64(invalidUser:1234) +BASIC_AUTH_INVALID_PASSWORD_HEADER = "Basic dGVzdDoxMjM0NQ==" # base64(test:12345) + +HEADERS = { + "Accept": "text/html", + "Accept-Encoding": "br;q=1.0, gzip;q=0.8, *;q=0.1", + "Accept-Language": "en-GB, *;q=0.5", + "Content-Language": "en-GB", + "Content-Length": "0", + "Content-Type": "application/x-www-form-urlencoded; charset=utf-8", + # removed because the request is not using this encoding to make the request and makes the test fail + # "Content-Encoding": "deflate, gzip", + "Host": "127.0.0.1:1234", + "User-Agent": "Benign User Agent 1.0", + "X-Forwarded-For": "42.42.42.42, 43.43.43.43", + "X-Client-IP": "42.42.42.42, 43.43.43.43", + "X-Real-IP": "42.42.42.42, 43.43.43.43", + "X-Forwarded": "42.42.42.42, 43.43.43.43", + "X-Cluster-Client-IP": "42.42.42.42, 43.43.43.43", + "Forwarded-For": "42.42.42.42, 43.43.43.43", + "Forwarded": "42.42.42.42, 43.43.43.43", + "Via": "42.42.42.42, 43.43.43.43", + "True-Client-IP": "42.42.42.42, 43.43.43.43", +} @rfc("https://docs.google.com/document/d/1-trUpphvyZY7k5ldjhW-MgqWl0xOm7AMEQDJEAZ63_Q/edit#heading=h.8d3o7vtyu1y1") @features.user_monitoring class Test_Login_Events: "Test login success/failure use cases" + # User entries in the internal DB: # users = [ # { @@ -36,263 +84,217 @@ class Test_Login_Events: # } # ] - @property - def username_key(self): - """ In Rails the parametesr are group by scope. In the case of the test the scope is user. The syntax to group parameters in a POST request is scope[parameter] """ - return "user[username]" if "rails" in context.weblog_variant else "username" - - @property - def password_key(self): - """ In Rails the parametesr are group by scope. In the case of the test the scope is user. The syntax to group parameters in a POST request is scope[parameter] """ - return "user[password]" if "rails" in context.weblog_variant else "password" - - USER = "test" - UUID_USER = "testuuid" - PASSWORD = "1234" - INVALID_USER = "invalidUser" - - BASIC_AUTH_USER_HEADER = "Basic dGVzdDoxMjM0" # base64(test:1234) - BASIC_AUTH_USER_UUID_HEADER = "Basic dGVzdHV1aWQ6MTIzNA==" # base64(testuuid:1234) - BASIC_AUTH_INVALID_USER_HEADER = "Basic aW52YWxpZFVzZXI6MTIzNA==" # base64(invalidUser:1234) - BASIC_AUTH_INVALID_PASSWORD_HEADER = "Basic dGVzdDoxMjM0NQ==" # base64(test:12345) - def setup_login_pii_success_local(self): - self.r_pii_success = weblog.post( - "/login?auth=local", data={self.username_key: self.USER, self.password_key: self.PASSWORD} - ) + self.r_pii_success = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) - @bug(context.library < "nodejs@4.9.0", reason="Reports empty space in usr.id when id is a PII") + @bug(context.library < "nodejs@4.9.0", reason="APMRP-360") @irrelevant( - context.library == "python" and context.scenario.weblog_variant in ["django-poc", "python3.12"], + context.library == "python" and context.weblog_variant in ["django-poc", "python3.12"], reason="APM reports all user id for now on Django", ) def test_login_pii_success_local(self): assert self.r_pii_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_pii_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_pii_success): meta = span.get("meta", {}) assert "usr.id" not in meta assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "safe" assert meta["appsec.events.users.login.success.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_pii_success_basic(self): - self.r_pii_success = weblog.get("/login?auth=basic", headers={"Authorization": self.BASIC_AUTH_USER_HEADER}) + self.r_pii_success = weblog.get("/login?auth=basic", headers={"Authorization": BASIC_AUTH_USER_HEADER}) @missing_feature(context.library == "php", reason="Basic auth not implemented") - @bug(context.library < "nodejs@4.9.0", reason="Reports empty space in usr.id when id is a PII") + @bug(context.library < "nodejs@4.9.0", reason="APMRP-360") @irrelevant( - context.library == "python" and context.scenario.weblog_variant in ["django-poc", "python3.12"], + context.library == "python" and context.weblog_variant in ["django-poc", "python3.12"], reason="APM reports all user id for now on Django", ) - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) def test_login_pii_success_basic(self): assert self.r_pii_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_pii_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_pii_success): meta = span.get("meta", {}) assert "usr.id" not in meta assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "safe" assert meta["appsec.events.users.login.success.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_success_local(self): - self.r_success = weblog.post( - "/login?auth=local", data={self.username_key: self.UUID_USER, self.password_key: self.PASSWORD} - ) + self.r_success = weblog.post("/login?auth=local", data=login_data(context, UUID_USER, PASSWORD)) def test_login_success_local(self): assert self.r_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "safe" assert meta["appsec.events.users.login.success.track"] == "true" assert meta["usr.id"] == "591dc126-8431-4d0f-9509-b23318d3dce4" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_success_basic(self): - self.r_success = weblog.get("/login?auth=basic", headers={"Authorization": self.BASIC_AUTH_USER_UUID_HEADER}) + self.r_success = weblog.get("/login?auth=basic", headers={"Authorization": BASIC_AUTH_USER_UUID_HEADER}) @missing_feature(context.library == "php", reason="Basic auth not implemented") - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) def test_login_success_basic(self): assert self.r_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "safe" assert meta["appsec.events.users.login.success.track"] == "true" assert meta["usr.id"] == "591dc126-8431-4d0f-9509-b23318d3dce4" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_user_failure_local(self): - self.r_wrong_user_failure = weblog.post( - "/login?auth=local", data={self.username_key: self.INVALID_USER, self.password_key: self.PASSWORD} - ) + self.r_wrong_user_failure = weblog.post("/login?auth=local", data=login_data(context, INVALID_USER, PASSWORD)) - @bug(context.library < "nodejs@4.9.0", reason="Reports empty space in usr.id when id is a PII") + @bug(context.library < "nodejs@4.9.0", reason="APMRP-360") + @missing_feature(weblog_variant="spring-boot-openliberty", reason="weblog returns error 500") def test_login_wrong_user_failure_local(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - if context.library != "nodejs": - # Currently in nodejs there is no way to check if the user exists upon authentication failure so + if context.library != "nodejs" and context.library != "java": + # Currently in nodejs/java there is no way to check if the user exists upon authentication failure so # this assertion is disabled for this library. assert meta["appsec.events.users.login.failure.usr.exists"] == "false" assert "appsec.events.users.login.failure.usr.id" not in meta assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "safe" assert meta["appsec.events.users.login.failure.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_user_failure_basic(self): self.r_wrong_user_failure = weblog.get( - "/login?auth=basic", headers={"Authorization": self.BASIC_AUTH_INVALID_USER_HEADER} + "/login?auth=basic", headers={"Authorization": BASIC_AUTH_INVALID_USER_HEADER} ) @missing_feature(context.library == "php", reason="Basic auth not implemented") - @bug(context.library < "nodejs@4.9.0", reason="Reports empty space in usr.id when id is a PII") - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) + @bug(context.library < "nodejs@4.9.0", reason="APMRP-360") + @missing_feature(weblog_variant="spring-boot-openliberty", reason="weblog returns error 500") def test_login_wrong_user_failure_basic(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - if context.library != "nodejs": - # Currently in nodejs there is no way to check if the user exists upon authentication failure so + if context.library != "nodejs" and context.library != "java": + # Currently in nodejs/java there is no way to check if the user exists upon authentication failure so # this assertion is disabled for this library. assert meta["appsec.events.users.login.failure.usr.exists"] == "false" assert "appsec.events.users.login.failure.usr.id" not in meta assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "safe" assert meta["appsec.events.users.login.failure.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_password_failure_local(self): - self.r_wrong_user_failure = weblog.post( - "/login?auth=local", data={self.username_key: self.USER, self.password_key: "12345"} - ) + self.r_wrong_user_failure = weblog.post("/login?auth=local", data=login_data(context, USER, "12345")) - @bug(context.library < "nodejs@4.9.0", reason="Reports empty space in usr.id when id is a PII") + @bug(context.library < "nodejs@4.9.0", reason="APMRP-360") + @missing_feature(weblog_variant="spring-boot-openliberty", reason="weblog returns error 500") def test_login_wrong_password_failure_local(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - if context.library != "nodejs": - # Currently in nodejs there is no way to check if the user exists upon authentication failure so + if context.library != "nodejs" and context.library != "java": + # Currently in nodejs/java there is no way to check if the user exists upon authentication failure so # this assertion is disabled for this library. assert meta["appsec.events.users.login.failure.usr.exists"] == "true" assert "appsec.events.users.login.failure.usr.id" not in meta assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "safe" assert meta["appsec.events.users.login.failure.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_password_failure_basic(self): self.r_wrong_user_failure = weblog.get( - "/login?auth=basic", headers={"Authorization": self.BASIC_AUTH_INVALID_PASSWORD_HEADER} + "/login?auth=basic", headers={"Authorization": BASIC_AUTH_INVALID_PASSWORD_HEADER} ) @missing_feature(context.library == "php", reason="Basic auth not implemented") - @bug(context.library < "nodejs@4.9.0", reason="Reports empty space in usr.id when id is a PII") - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) + @bug(context.library < "nodejs@4.9.0", reason="APMRP-360") + @missing_feature(weblog_variant="spring-boot-openliberty", reason="weblog returns error 500") def test_login_wrong_password_failure_basic(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - if context.library != "nodejs": - # Currently in nodejs there is no way to check if the user exists upon authentication failure so + if context.library != "nodejs" and context.library != "java": + # Currently in nodejs/java there is no way to check if the user exists upon authentication failure so # this assertion is disabled for this library. assert meta["appsec.events.users.login.failure.usr.exists"] == "true" assert "appsec.events.users.login.failure.usr.id" not in meta assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "safe" assert meta["appsec.events.users.login.failure.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_success_local(self): self.r_sdk_success = weblog.post( "/login?auth=local&sdk_event=success&sdk_user=sdkUser", - data={self.username_key: self.USER, self.password_key: self.PASSWORD}, + data=login_data(context, USER, PASSWORD), ) def test_login_sdk_success_local(self): assert self.r_sdk_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "safe" assert meta["_dd.appsec.events.users.login.success.sdk"] == "true" assert meta["appsec.events.users.login.success.track"] == "true" assert meta["usr.id"] == "sdkUser" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_success_basic(self): self.r_sdk_success = weblog.get( "/login?auth=basic&sdk_event=success&sdk_user=sdkUser", - headers={"Authorization": self.BASIC_AUTH_USER_HEADER}, + headers={"Authorization": BASIC_AUTH_USER_HEADER}, ) @missing_feature(context.library == "php", reason="Basic auth not implemented") - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) def test_login_sdk_success_basic(self): assert self.r_sdk_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "safe" assert meta["_dd.appsec.events.users.login.success.sdk"] == "true" assert meta["appsec.events.users.login.success.track"] == "true" assert meta["usr.id"] == "sdkUser" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_failure_local(self): self.r_sdk_failure = weblog.post( "/login?auth=local&sdk_event=failure&sdk_user=sdkUser&sdk_user_exists=true", - data={self.username_key: self.INVALID_USER, self.password_key: self.PASSWORD}, + data=login_data(context, INVALID_USER, PASSWORD), ) + @missing_feature(weblog_variant="spring-boot-openliberty", reason="weblog returns error 500") def test_login_sdk_failure_local(self): assert self.r_sdk_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_failure): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "safe" assert meta["_dd.appsec.events.users.login.failure.sdk"] == "true" assert meta["appsec.events.users.login.failure.track"] == "true" assert meta["appsec.events.users.login.failure.usr.id"] == "sdkUser" assert meta["appsec.events.users.login.failure.usr.exists"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_failure_basic(self): self.r_sdk_failure = weblog.get( "/login?auth=basic&sdk_event=failure&sdk_user=sdkUser&sdk_user_exists=true", - headers={"Authorization": self.BASIC_AUTH_INVALID_USER_HEADER}, + headers={"Authorization": BASIC_AUTH_INVALID_USER_HEADER}, ) @missing_feature(context.library == "php", reason="Basic auth not implemented") - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) + @missing_feature(weblog_variant="spring-boot-openliberty", reason="weblog returns error 500") def test_login_sdk_failure_basic(self): assert self.r_sdk_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_failure): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "safe" assert meta["_dd.appsec.events.users.login.failure.sdk"] == "true" assert meta["appsec.events.users.login.failure.track"] == "true" assert meta["appsec.events.users.login.failure.usr.id"] == "sdkUser" assert meta["appsec.events.users.login.failure.usr.exists"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) @rfc("https://docs.google.com/document/d/1-trUpphvyZY7k5ldjhW-MgqWl0xOm7AMEQDJEAZ63_Q/edit#heading=h.8d3o7vtyu1y1") @@ -301,52 +303,12 @@ def test_login_sdk_failure_basic(self): class Test_Login_Events_Extended: "Test login success/failure use cases" - @property - def username_key(self): - """ In Rails the parametesr are group by scope. In the case of the test the scope is user. The syntax to group parameters in a POST request is scope[parameter] """ - return "user[username]" if "rails" in context.weblog_variant else "username" - - @property - def password_key(self): - """ In Rails the parametesr are group by scope. In the case of the test the scope is user. The syntax to group parameters in a POST request is scope[parameter] """ - return "user[password]" if "rails" in context.weblog_variant else "password" - - USER = "test" - UUID_USER = "testuuid" - PASSWORD = "1234" - - BASIC_AUTH_USER_HEADER = "Basic dGVzdDoxMjM0" # base64(test:1234) - BASIC_AUTH_USER_UUID_HEADER = "Basic dGVzdHV1aWQ6MTIzNA==" # base64(testuuid:1234) - - HEADERS = { - "Accept": "text/html", - "Accept-Encoding": "br;q=1.0, gzip;q=0.8, *;q=0.1", - "Accept-Language": "en-GB, *;q=0.5", - "Content-Language": "en-GB", - "Content-Length": "0", - "Content-Type": "text/html; charset=utf-8", - "Content-Encoding": "deflate, gzip", - "Host": "127.0.0.1:1234", - "User-Agent": "Benign User Agent 1.0", - "X-Forwarded-For": "42.42.42.42, 43.43.43.43", - "X-Client-IP": "42.42.42.42, 43.43.43.43", - "X-Real-IP": "42.42.42.42, 43.43.43.43", - "X-Forwarded": "42.42.42.42, 43.43.43.43", - "X-Cluster-Client-IP": "42.42.42.42, 43.43.43.43", - "Forwarded-For": "42.42.42.42, 43.43.43.43", - "Forwarded": "42.42.42.42, 43.43.43.43", - "Via": "42.42.42.42, 43.43.43.43", - "True-Client-IP": "42.42.42.42, 43.43.43.43", - } - def setup_login_success_local(self): - self.r_success = weblog.post( - "/login?auth=local", data={self.username_key: self.USER, self.password_key: self.PASSWORD} - ) + self.r_success = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) def test_login_success_local(self): assert self.r_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "extended" assert meta["appsec.events.users.login.success.track"] == "true" @@ -364,54 +326,53 @@ def test_login_success_local(self): # theres no login field in ruby assert meta["usr.email"] == "testuser@ddog.com" assert meta["usr.username"] == "test" - else: + elif context.library != "java": + # there are no extra fields in java assert meta["usr.email"] == "testuser@ddog.com" assert meta["usr.username"] == "test" assert meta["usr.login"] == "test" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_success_basic(self): - self.r_success = weblog.get("/login?auth=basic", headers={"Authorization": self.BASIC_AUTH_USER_HEADER}) + self.r_success = weblog.get("/login?auth=basic", headers={"Authorization": BASIC_AUTH_USER_HEADER}) @missing_feature(context.library == "php", reason="Basic auth not implemented") - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) def test_login_success_basic(self): assert self.r_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "extended" assert meta["appsec.events.users.login.success.track"] == "true" assert meta["usr.id"] == "social-security-id" - assert meta["usr.email"] == "testuser@ddog.com" if context.library in ("dotnet", "python"): # theres no login field in dotnet # usr.name was in the sdk before so it was kept as is assert meta["usr.name"] == "test" + assert meta["usr.email"] == "testuser@ddog.com" elif context.library == "ruby": # theres no login field in ruby assert meta["usr.username"] == "test" - else: + assert meta["usr.email"] == "testuser@ddog.com" + elif context.library != "java": + # there are no extra fields in java assert meta["usr.username"] == "test" assert meta["usr.login"] == "test" + assert meta["usr.email"] == "testuser@ddog.com" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_user_failure_local(self): - self.r_wrong_user_failure = weblog.post( - "/login?auth=local", data={self.username_key: "invalidUser", self.password_key: self.PASSWORD} - ) + self.r_wrong_user_failure = weblog.post("/login?auth=local", data=login_data(context, INVALID_USER, PASSWORD)) + @missing_feature(weblog_variant="spring-boot-openliberty", reason="weblog returns error 500") def test_login_wrong_user_failure_local(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - if context.library != "nodejs": - # Currently in nodejs there is no way to check if the user exists upon authentication failure so + if context.library != "nodejs" and context.library != "java": + # Currently in nodejs/java there is no way to check if the user exists upon authentication failure so # this assertion is disabled for this library. assert meta["appsec.events.users.login.failure.usr.exists"] == "false" @@ -420,28 +381,29 @@ def test_login_wrong_user_failure_local(self): if context.library == "ruby": # In ruby we do not have access to the user object since it fails with invalid username # For that reason we can not extract id, email or username - assert meta.get("appsec.events.users.login.failure.usr.id") == None - assert meta.get("appsec.events.users.login.failure.usr.email") == None - assert meta.get("appsec.events.users.login.failure.usr.username") == None + assert meta.get("appsec.events.users.login.failure.usr.id") is None + assert meta.get("appsec.events.users.login.failure.usr.email") is None + assert meta.get("appsec.events.users.login.failure.usr.username") is None elif context.library == "dotnet": # in dotnet if the user doesn't exist, there is no id (generated upon user creation) - assert meta["appsec.events.users.login.failure.username"] == "invalidUser" + assert meta["appsec.events.users.login.failure.username"] == INVALID_USER else: - assert meta["appsec.events.users.login.failure.usr.id"] == "invalidUser" - assert_priority(span, meta) + assert meta["appsec.events.users.login.failure.usr.id"] == INVALID_USER + assert_priority(span, trace) def setup_login_wrong_user_failure_basic(self): self.r_wrong_user_failure = weblog.get( - "/login?auth=basic", headers={"Authorization": "Basic aW52YWxpZFVzZXI6MTIzNA=="} + "/login?auth=basic", headers={"Authorization": BASIC_AUTH_INVALID_USER_HEADER} ) @missing_feature(context.library == "php", reason="Basic auth not implemented") + @missing_feature(weblog_variant="spring-boot-openliberty", reason="weblog returns error 500") def test_login_wrong_user_failure_basic(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - if context.library != "nodejs": - # Currently in nodejs there is no way to check if the user exists upon authentication failure so + if context.library != "nodejs" and context.library != "java": + # Currently in nodejs/java there is no way to check if the user exists upon authentication failure so # this assertion is disabled for this library. assert meta["appsec.events.users.login.failure.usr.exists"] == "false" @@ -450,27 +412,26 @@ def test_login_wrong_user_failure_basic(self): if context.library == "ruby": # In ruby we do not have access to the user object since it fails with invalid username # For that reason we can not extract id, email or username - assert meta.get("appsec.events.users.login.failure.usr.id") == None - assert meta.get("appsec.events.users.login.failure.usr.email") == None - assert meta.get("appsec.events.users.login.failure.usr.username") == None + assert meta.get("appsec.events.users.login.failure.usr.id") is None + assert meta.get("appsec.events.users.login.failure.usr.email") is None + assert meta.get("appsec.events.users.login.failure.usr.username") is None elif context.library == "dotnet": # in dotnet if the user doesn't exist, there is no id (generated upon user creation) - assert meta["appsec.events.users.login.failure.username"] == "invalidUser" + assert meta["appsec.events.users.login.failure.username"] == INVALID_USER else: - assert meta["appsec.events.users.login.failure.usr.id"] == "invalidUser" - assert_priority(span, meta) + assert meta["appsec.events.users.login.failure.usr.id"] == INVALID_USER + assert_priority(span, trace) def setup_login_wrong_password_failure_local(self): - self.r_wrong_user_failure = weblog.post( - "/login?auth=local", data={self.username_key: self.USER, self.password_key: "12345"} - ) + self.r_wrong_user_failure = weblog.post("/login?auth=local", data=login_data(context, USER, "12345")) + @missing_feature(weblog_variant="spring-boot-openliberty", reason="weblog returns error 500") def test_login_wrong_password_failure_local(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - if context.library == "nodejs": - # Currently in nodejs there is no way to check if the user exists upon authentication failure so + if context.library == "nodejs" or context.library == "java": + # Currently in nodejs/java there is no way to check if the user exists upon authentication failure so # this assertion is disabled for this library. assert meta["appsec.events.users.login.failure.usr.id"] == "test" else: @@ -482,22 +443,21 @@ def test_login_wrong_password_failure_local(self): assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "extended" assert meta["appsec.events.users.login.failure.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_password_failure_basic(self): - self.r_wrong_user_failure = weblog.get("/login?auth=basic", headers={"Authorization": "Basic dGVzdDoxMjM0NQ=="}) + self.r_wrong_user_failure = weblog.get( + "/login?auth=basic", headers={"Authorization": BASIC_AUTH_INVALID_PASSWORD_HEADER} + ) @missing_feature(context.library == "php", reason="Basic auth not implemented") - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) + @missing_feature(weblog_variant="spring-boot-openliberty", reason="weblog returns error 500") def test_login_wrong_password_failure_basic(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - if context.library != "nodejs": - # Currently in nodejs there is no way to check if the user exists upon authentication failure so + if context.library != "nodejs" and context.library != "java": + # Currently in nodejs/java there is no way to check if the user exists upon authentication failure so # this assertion is disabled for this library. assert meta["appsec.events.users.login.failure.usr.exists"] == "true" assert meta["appsec.events.users.login.failure.usr.id"] == "social-security-id" @@ -509,94 +469,87 @@ def test_login_wrong_password_failure_basic(self): assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "extended" assert meta["appsec.events.users.login.failure.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_success_local(self): self.r_sdk_success = weblog.post( "/login?auth=local&sdk_event=success&sdk_user=sdkUser", - data={self.username_key: self.USER, self.password_key: self.PASSWORD}, + data=login_data(context, USER, PASSWORD), ) def test_login_sdk_success_local(self): assert self.r_sdk_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "extended" assert meta["_dd.appsec.events.users.login.success.sdk"] == "true" assert meta["appsec.events.users.login.success.track"] == "true" assert meta["usr.id"] == "sdkUser" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_success_basic(self): self.r_sdk_success = weblog.get( "/login?auth=basic&sdk_event=success&sdk_user=sdkUser", - headers={"Authorization": self.BASIC_AUTH_USER_HEADER}, + headers={"Authorization": BASIC_AUTH_USER_HEADER}, ) @missing_feature(context.library == "php", reason="Basic auth not implemented") - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) def test_login_sdk_success_basic(self): assert self.r_sdk_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "extended" assert meta["_dd.appsec.events.users.login.success.sdk"] == "true" assert meta["appsec.events.users.login.success.track"] == "true" assert meta["usr.id"] == "sdkUser" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_failure_basic(self): self.r_sdk_failure = weblog.get( "/login?auth=basic&sdk_event=failure&sdk_user=sdkUser&sdk_user_exists=true", - headers={"Authorization": "Basic aW52YWxpZFVzZXI6MTIzNA=="}, + headers={"Authorization": BASIC_AUTH_INVALID_USER_HEADER}, ) @missing_feature(context.library == "php", reason="Basic auth not implemented") - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) + @missing_feature(weblog_variant="spring-boot-openliberty", reason="weblog returns error 500") def test_login_sdk_failure_basic(self): assert self.r_sdk_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_failure): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "extended" assert meta["_dd.appsec.events.users.login.failure.sdk"] == "true" assert meta["appsec.events.users.login.failure.track"] == "true" assert meta["appsec.events.users.login.failure.usr.id"] == "sdkUser" assert meta["appsec.events.users.login.failure.usr.exists"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_failure_local(self): self.r_sdk_failure = weblog.post( "/login?auth=local&sdk_event=failure&sdk_user=sdkUser&sdk_user_exists=true", - data={self.username_key: "invalidUser", self.password_key: self.PASSWORD}, + data=login_data(context, INVALID_USER, PASSWORD), ) + @missing_feature(weblog_variant="spring-boot-openliberty", reason="weblog returns error 500") def test_login_sdk_failure_local(self): assert self.r_sdk_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_failure): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "extended" assert meta["_dd.appsec.events.users.login.failure.sdk"] == "true" assert meta["appsec.events.users.login.failure.track"] == "true" assert meta["appsec.events.users.login.failure.usr.id"] == "sdkUser" assert meta["appsec.events.users.login.failure.usr.exists"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_success_headers(self): self.r_hdr_success = weblog.post( "/login?auth=local", - data={self.username_key: self.USER, self.password_key: self.PASSWORD}, - headers=self.HEADERS, + data=login_data(context, USER, PASSWORD), + headers=HEADERS, ) - @missing_feature(library="dotnet") - @missing_feature(library="java") - @missing_feature(library="nodejs") + @missing_feature(context.library < "dotnet@3.7.0") + @missing_feature(context.library < "nodejs@5.18.0") @missing_feature(library="php") @missing_feature(library="ruby") def test_login_success_headers(self): @@ -606,7 +559,7 @@ def validate_login_success_headers(span): if span.get("parent_id") not in (0, None): return - for header in self.HEADERS: + for header in HEADERS: assert f"http.request.headers.{header.lower()}" in span["meta"], f"Can't find {header} in span's meta" return True @@ -615,13 +568,12 @@ def validate_login_success_headers(span): def setup_login_failure_headers(self): self.r_hdr_failure = weblog.post( "/login?auth=local", - data={self.username_key: "invalidUser", self.password_key: self.PASSWORD}, - headers=self.HEADERS, + data=login_data(context, INVALID_USER, PASSWORD), + headers=HEADERS, ) - @missing_feature(library="dotnet") - @missing_feature(library="java") - @missing_feature(library="nodejs") + @missing_feature(context.library < "dotnet@3.7.0") + @missing_feature(context.library < "nodejs@5.18.0") @missing_feature(library="php") @missing_feature(library="ruby") def test_login_failure_headers(self): @@ -631,7 +583,7 @@ def validate_login_failure_headers(span): if span.get("parent_id") not in (0, None): return - for header in self.HEADERS: + for header in HEADERS: assert f"http.request.headers.{header.lower()}" in span["meta"], f"Can't find {header} in span's meta" return True @@ -640,6 +592,7 @@ def validate_login_failure_headers(span): @rfc("https://docs.google.com/document/d/19VHLdJLVFwRb_JrE87fmlIM5CL5LdOBv4AmLxgdo9qI/edit") @features.user_monitoring +@features.user_id_collection_modes class Test_V2_Login_Events: """ Test login success/failure use cases @@ -662,34 +615,12 @@ class Test_V2_Login_Events: # } # ] - @property - def username_key(self): - """ In Rails the parametesr are group by scope. In the case of the test the scope is user. The syntax to group parameters in a POST request is scope[parameter] """ - return "user[username]" if "rails" in context.weblog_variant else "username" - - @property - def password_key(self): - """ In Rails the parametesr are group by scope. In the case of the test the scope is user. The syntax to group parameters in a POST request is scope[parameter] """ - return "user[password]" if "rails" in context.weblog_variant else "password" - - USER = "test" - UUID_USER = "testuuid" - PASSWORD = "1234" - INVALID_USER = "invalidUser" - - BASIC_AUTH_USER_HEADER = "Basic dGVzdDoxMjM0" # base64(test:1234) - BASIC_AUTH_USER_UUID_HEADER = "Basic dGVzdHV1aWQ6MTIzNA==" # base64(testuuid:1234) - BASIC_AUTH_INVALID_USER_HEADER = "Basic aW52YWxpZFVzZXI6MTIzNA==" # base64(invalidUser:1234) - BASIC_AUTH_INVALID_PASSWORD_HEADER = "Basic dGVzdDoxMjM0NQ==" # base64(test:12345) - def setup_login_pii_success_local(self): - self.r_pii_success = weblog.post( - "/login?auth=local", data={self.username_key: self.USER, self.password_key: self.PASSWORD} - ) + self.r_pii_success = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) def test_login_pii_success_local(self): assert self.r_pii_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_pii_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_pii_success): meta = span.get("meta", {}) assert "usr.id" in meta assert meta["usr.id"] == "social-security-id" @@ -699,18 +630,15 @@ def test_login_pii_success_local(self): assert "appsec.events.users.login.success.login" not in meta assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "identification" assert meta["appsec.events.users.login.success.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_pii_success_basic(self): - self.r_pii_success = weblog.get("/login?auth=basic", headers={"Authorization": self.BASIC_AUTH_USER_HEADER}) + self.r_pii_success = weblog.get("/login?auth=basic", headers={"Authorization": BASIC_AUTH_USER_HEADER}) - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) + @missing_feature(context.library == "php", reason="Basic auth not implemented") def test_login_pii_success_basic(self): assert self.r_pii_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_pii_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_pii_success): meta = span.get("meta", {}) assert "usr.id" in meta assert meta["usr.id"] == "social-security-id" @@ -720,16 +648,14 @@ def test_login_pii_success_basic(self): assert "appsec.events.users.login.success.login" not in meta assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "identification" assert meta["appsec.events.users.login.success.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_success_local(self): - self.r_success = weblog.post( - "/login?auth=local", data={self.username_key: self.UUID_USER, self.password_key: self.PASSWORD} - ) + self.r_success = weblog.post("/login?auth=local", data=login_data(context, UUID_USER, PASSWORD)) def test_login_success_local(self): assert self.r_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "identification" assert meta["appsec.events.users.login.success.track"] == "true" @@ -738,18 +664,15 @@ def test_login_success_local(self): assert "appsec.events.users.login.success.email" not in meta assert "appsec.events.users.login.success.username" not in meta assert "appsec.events.users.login.success.login" not in meta - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_success_basic(self): - self.r_success = weblog.get("/login?auth=basic", headers={"Authorization": self.BASIC_AUTH_USER_UUID_HEADER}) + self.r_success = weblog.get("/login?auth=basic", headers={"Authorization": BASIC_AUTH_USER_UUID_HEADER}) - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) + @missing_feature(context.library == "php", reason="Basic auth not implemented") def test_login_success_basic(self): assert self.r_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "identification" assert meta["appsec.events.users.login.success.track"] == "true" @@ -758,237 +681,201 @@ def test_login_success_basic(self): assert "appsec.events.users.login.success.email" not in meta assert "appsec.events.users.login.success.username" not in meta assert "appsec.events.users.login.success.login" not in meta - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_user_failure_local(self): - self.r_wrong_user_failure = weblog.post( - "/login?auth=local", data={self.username_key: self.INVALID_USER, self.password_key: self.PASSWORD} - ) + self.r_wrong_user_failure = weblog.post("/login?auth=local", data=login_data(context, INVALID_USER, PASSWORD)) + @irrelevant( + context.library >= "dotnet@3.7.0", reason="Released v3 with logins from 3.7, now it's ...failure.usr.login" + ) def test_login_wrong_user_failure_local(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - if context.library != "nodejs": - # Currently in nodejs there is no way to check if the user exists upon authentication failure so + if context.library != "nodejs" and context.library != "java": + # Currently in nodejs/java there is no way to check if the user exists upon authentication failure so # this assertion is disabled for this library. assert meta["appsec.events.users.login.failure.usr.exists"] == "false" - assert meta["appsec.events.users.login.failure.usr.id"] == "invalidUser" + assert meta["appsec.events.users.login.failure.usr.id"] == INVALID_USER assert "appsec.events.users.login.failure.usr.email" not in meta assert "appsec.events.users.login.failure.usr.login" not in meta assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "identification" assert meta["appsec.events.users.login.failure.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_user_failure_basic(self): self.r_wrong_user_failure = weblog.get( - "/login?auth=basic", headers={"Authorization": self.BASIC_AUTH_INVALID_USER_HEADER} + "/login?auth=basic", headers={"Authorization": BASIC_AUTH_INVALID_USER_HEADER} ) + @missing_feature(context.library == "php", reason="Basic auth not implemented") @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", + context.library >= "dotnet@3.7.0", reason="Released v3 with logins from 3.7, now it's ...failure.usr.login" ) def test_login_wrong_user_failure_basic(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - if context.library != "nodejs": - # Currently in nodejs there is no way to check if the user exists upon authentication failure so + if context.library != "nodejs" and context.library != "java": + # Currently in nodejs/java there is no way to check if the user exists upon authentication failure so # this assertion is disabled for this library. assert meta["appsec.events.users.login.failure.usr.exists"] == "false" - assert meta["appsec.events.users.login.failure.usr.id"] == "invalidUser" + assert meta["appsec.events.users.login.failure.usr.id"] == INVALID_USER assert "appsec.events.users.login.failure.usr.email" not in meta assert "appsec.events.users.login.failure.usr.login" not in meta assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "identification" assert meta["appsec.events.users.login.failure.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_password_failure_local(self): - self.r_wrong_user_failure = weblog.post( - "/login?auth=local", data={self.username_key: self.USER, self.password_key: "12345"} - ) + self.r_wrong_user_failure = weblog.post("/login?auth=local", data=login_data(context, USER, "12345")) + @irrelevant( + context.library >= "dotnet@3.7.0", reason="Released v3 with logins from 3.7, now exists ...failure.usr.login" + ) def test_login_wrong_password_failure_local(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - if context.library != "nodejs": - # Currently in nodejs there is no way to check if the user exists upon authentication failure so + if context.library != "nodejs" and context.library != "java": + # Currently in nodejs/java there is no way to check if the user exists upon authentication failure so # this assertion is disabled for this library. assert meta["appsec.events.users.login.failure.usr.exists"] == "true" assert "appsec.events.users.login.failure.usr.id" in meta - assert meta["appsec.events.users.login.failure.usr.id"] == "social-security-id" + if context.library == "java": + # in case of failure java only has access to the original username sent in the request + assert meta["appsec.events.users.login.failure.usr.id"] == "test" + else: + assert meta["appsec.events.users.login.failure.usr.id"] == "social-security-id" # deprecated assert "appsec.events.users.login.failure.usr.email" not in meta assert "appsec.events.users.login.failure.usr.login" not in meta assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "identification" assert meta["appsec.events.users.login.failure.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_password_failure_basic(self): self.r_wrong_user_failure = weblog.get( - "/login?auth=basic", headers={"Authorization": self.BASIC_AUTH_INVALID_PASSWORD_HEADER} + "/login?auth=basic", headers={"Authorization": BASIC_AUTH_INVALID_PASSWORD_HEADER} ) + @missing_feature(context.library == "php", reason="Basic auth not implemented") @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", + context.library >= "dotnet@3.7.0", reason="Released v3 with logins from 3.7, now exists ...failure.usr.login" ) def test_login_wrong_password_failure_basic(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - if context.library != "nodejs": - # Currently in nodejs there is no way to check if the user exists upon authentication failure so + if context.library != "nodejs" and context.library != "java": + # Currently in nodejs/java there is no way to check if the user exists upon authentication failure so # this assertion is disabled for this library. assert meta["appsec.events.users.login.failure.usr.exists"] == "true" assert "appsec.events.users.login.failure.usr.id" in meta - assert meta["appsec.events.users.login.failure.usr.id"] == "social-security-id" + if context.library == "java": + # in case of failure java only has access to the original username sent in the request + assert meta["appsec.events.users.login.failure.usr.id"] == "test" + else: + assert meta["appsec.events.users.login.failure.usr.id"] == "social-security-id" assert "appsec.events.users.login.failure.usr.email" not in meta assert "appsec.events.users.login.failure.usr.login" not in meta assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "identification" assert meta["appsec.events.users.login.failure.track"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_success_local(self): self.r_sdk_success = weblog.post( "/login?auth=local&sdk_event=success&sdk_user=sdkUser", - data={self.username_key: self.USER, self.password_key: self.PASSWORD}, + data=login_data(context, USER, PASSWORD), ) def test_login_sdk_success_local(self): assert self.r_sdk_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "identification" assert meta["_dd.appsec.events.users.login.success.sdk"] == "true" assert meta["appsec.events.users.login.success.track"] == "true" assert meta["usr.id"] == "sdkUser" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_success_basic(self): self.r_sdk_success = weblog.get( "/login?auth=basic&sdk_event=success&sdk_user=sdkUser", - headers={"Authorization": self.BASIC_AUTH_USER_HEADER}, + headers={"Authorization": BASIC_AUTH_USER_HEADER}, ) - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) + @missing_feature(context.library == "php", reason="Basic auth not implemented") def test_login_sdk_success_basic(self): assert self.r_sdk_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "identification" assert meta["_dd.appsec.events.users.login.success.sdk"] == "true" assert meta["appsec.events.users.login.success.track"] == "true" assert meta["usr.id"] == "sdkUser" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_failure_local(self): self.r_sdk_failure = weblog.post( "/login?auth=local&sdk_event=failure&sdk_user=sdkUser&sdk_user_exists=true", - data={self.username_key: self.INVALID_USER, self.password_key: self.PASSWORD}, + data=login_data(context, INVALID_USER, PASSWORD), ) def test_login_sdk_failure_local(self): assert self.r_sdk_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_failure): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "identification" assert meta["_dd.appsec.events.users.login.failure.sdk"] == "true" assert meta["appsec.events.users.login.failure.track"] == "true" assert meta["appsec.events.users.login.failure.usr.id"] == "sdkUser" assert meta["appsec.events.users.login.failure.usr.exists"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_failure_basic(self): self.r_sdk_failure = weblog.get( "/login?auth=basic&sdk_event=failure&sdk_user=sdkUser&sdk_user_exists=true", - headers={"Authorization": self.BASIC_AUTH_INVALID_USER_HEADER}, + headers={"Authorization": BASIC_AUTH_INVALID_USER_HEADER}, ) - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) + @missing_feature(context.library == "php", reason="Basic auth not implemented") def test_login_sdk_failure_basic(self): assert self.r_sdk_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_failure): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "identification" assert meta["_dd.appsec.events.users.login.failure.sdk"] == "true" assert meta["appsec.events.users.login.failure.track"] == "true" assert meta["appsec.events.users.login.failure.usr.id"] == "sdkUser" assert meta["appsec.events.users.login.failure.usr.exists"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) @rfc("https://docs.google.com/document/d/19VHLdJLVFwRb_JrE87fmlIM5CL5LdOBv4AmLxgdo9qI/edit") @scenarios.appsec_auto_events_extended @features.user_monitoring +@features.user_id_collection_modes class Test_V2_Login_Events_Anon: """Test login success/failure use cases - As default mode is identification, this scenario will test anonymization. + As default mode is identification, this scenario will test anonymization. """ - @property - def username_key(self): - """ In Rails the parametesr are group by scope. In the case of the test the scope is user. The syntax to group parameters in a POST request is scope[parameter] """ - return "user[username]" if "rails" in context.weblog_variant else "username" - - @property - def password_key(self): - """ In Rails the parametesr are group by scope. In the case of the test the scope is user. The syntax to group parameters in a POST request is scope[parameter] """ - return "user[password]" if "rails" in context.weblog_variant else "password" - - USER = "test" - USER_HASH = "anon_5f31ffaf95946d2dc703ddc96a100de5" - UUID_USER = "testuuid" - PASSWORD = "1234" - - BASIC_AUTH_USER_HEADER = "Basic dGVzdDoxMjM0" # base64(test:1234) - BASIC_AUTH_USER_UUID_HEADER = "Basic dGVzdHV1aWQ6MTIzNA==" # base64(testuuid:1234) - - HEADERS = { - "Accept": "text/html", - "Accept-Encoding": "br;q=1.0, gzip;q=0.8, *;q=0.1", - "Accept-Language": "en-GB, *;q=0.5", - "Content-Language": "en-GB", - "Content-Length": "0", - "Content-Type": "text/html; charset=utf-8", - "Content-Encoding": "deflate, gzip", - "Host": "127.0.0.1:1234", - "User-Agent": "Benign User Agent 1.0", - "X-Forwarded-For": "42.42.42.42, 43.43.43.43", - "X-Client-IP": "42.42.42.42, 43.43.43.43", - "X-Real-IP": "42.42.42.42, 43.43.43.43", - "X-Forwarded": "42.42.42.42, 43.43.43.43", - "X-Cluster-Client-IP": "42.42.42.42, 43.43.43.43", - "Forwarded-For": "42.42.42.42, 43.43.43.43", - "Forwarded": "42.42.42.42, 43.43.43.43", - "Via": "42.42.42.42, 43.43.43.43", - "True-Client-IP": "42.42.42.42, 43.43.43.43", - } - def setup_login_success_local(self): - self.r_success = weblog.post( - "/login?auth=local", data={self.username_key: self.USER, self.password_key: self.PASSWORD} - ) + self.r_success = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) def test_login_success_local(self): assert self.r_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "anonymization" assert meta["appsec.events.users.login.success.track"] == "true" - assert meta["usr.id"] == self.USER_HASH + assert meta["usr.id"] == USER_HASH # deprecated "appsec.events.users.login.success.username" not in meta @@ -997,22 +884,19 @@ def test_login_success_local(self): "usr.username" not in meta "usr.login" not in meta - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_success_basic(self): - self.r_success = weblog.get("/login?auth=basic", headers={"Authorization": self.BASIC_AUTH_USER_HEADER}) + self.r_success = weblog.get("/login?auth=basic", headers={"Authorization": BASIC_AUTH_USER_HEADER}) - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) + @missing_feature(context.library == "php", reason="Basic auth not implemented") def test_login_success_basic(self): assert self.r_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "anonymization" assert meta["appsec.events.users.login.success.track"] == "true" - assert meta["usr.id"] == self.USER_HASH + assert meta["usr.id"] == USER_HASH # deprecated "appsec.events.users.login.success.username" not in meta @@ -1021,173 +905,184 @@ def test_login_success_basic(self): "usr.username" not in meta "usr.login" not in meta - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_user_failure_local(self): - self.r_wrong_user_failure = weblog.post( - "/login?auth=local", data={self.username_key: "invalidUser", self.password_key: self.PASSWORD} - ) + self.r_wrong_user_failure = weblog.post("/login?auth=local", data=login_data(context, INVALID_USER, PASSWORD)) + @irrelevant( + context.library >= "dotnet@3.7.0", + reason="Released v3 with logins from 3.7, now login reported when user exists is false", + ) def test_login_wrong_user_failure_local(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) assert meta["appsec.events.users.login.failure.usr.exists"] == "false" assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "anonymization" assert meta["appsec.events.users.login.failure.track"] == "true" - assert meta["appsec.events.users.login.failure.usr.id"] == "anon_2141e3bee69f7de45b4f1d8d1f29258a" + assert meta["appsec.events.users.login.failure.usr.id"] == INVALID_USER_HASH assert "appsec.events.users.login.failure.email" not in meta assert "appsec.events.users.login.failure.username" not in meta - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_user_failure_basic(self): self.r_wrong_user_failure = weblog.get( - "/login?auth=basic", headers={"Authorization": "Basic aW52YWxpZFVzZXI6MTIzNA=="} + "/login?auth=basic", headers={"Authorization": BASIC_AUTH_INVALID_USER_HEADER} ) + @missing_feature(context.library == "php", reason="Basic auth not implemented") @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", + context.library >= "dotnet@3.7.0", + reason="Released v3 with logins from 3.7, now login reported when user exists is false", ) def test_login_wrong_user_failure_basic(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) assert meta["appsec.events.users.login.failure.usr.exists"] == "false" assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "anonymization" assert meta["appsec.events.users.login.failure.track"] == "true" - assert meta["appsec.events.users.login.failure.usr.id"] == "anon_2141e3bee69f7de45b4f1d8d1f29258a" + assert meta["appsec.events.users.login.failure.usr.id"] == INVALID_USER_HASH assert "appsec.events.users.login.failure.email" not in meta assert "appsec.events.users.login.failure.username" not in meta - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_password_failure_local(self): - self.r_wrong_user_failure = weblog.post( - "/login?auth=local", data={self.username_key: self.USER, self.password_key: "12345"} - ) + self.r_wrong_user_failure = weblog.post("/login?auth=local", data=login_data(context, USER, "12345")) def test_login_wrong_password_failure_local(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - assert meta["appsec.events.users.login.failure.usr.exists"] == "true" + if context.library != "java": + # Currently in java there is no way to check if the user exists upon authentication failure so + # this assertion is disabled for this library. + assert meta["appsec.events.users.login.failure.usr.exists"] == "true" + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "anonymization" assert meta["appsec.events.users.login.failure.track"] == "true" - assert meta["appsec.events.users.login.failure.usr.id"] == self.USER_HASH + if context.library == "java": + # in case of failure java only has access to the original username sent in the request + assert meta["appsec.events.users.login.failure.usr.id"] == USERNAME_HASH + else: + assert meta["appsec.events.users.login.failure.usr.id"] == USER_HASH assert "appsec.events.users.login.failure.email" not in meta assert "appsec.events.users.login.failure.username" not in meta - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_wrong_password_failure_basic(self): - self.r_wrong_user_failure = weblog.get("/login?auth=basic", headers={"Authorization": "Basic dGVzdDoxMjM0NQ=="}) + self.r_wrong_user_failure = weblog.get( + "/login?auth=basic", headers={"Authorization": BASIC_AUTH_INVALID_PASSWORD_HEADER} + ) - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) + @missing_feature(context.library == "php", reason="Basic auth not implemented") def test_login_wrong_password_failure_basic(self): assert self.r_wrong_user_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): meta = span.get("meta", {}) - assert meta["appsec.events.users.login.failure.usr.exists"] == "true" + if context.library != "java": + # Currently in java there is no way to check if the user exists upon authentication failure so + # this assertion is disabled for this library. + assert meta["appsec.events.users.login.failure.usr.exists"] == "true" + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "anonymization" assert meta["appsec.events.users.login.failure.track"] == "true" - assert meta["appsec.events.users.login.failure.usr.id"] == self.USER_HASH + if context.library == "java": + # in case of failure java only has access to the original username sent in the request + assert meta["appsec.events.users.login.failure.usr.id"] == USERNAME_HASH + else: + assert meta["appsec.events.users.login.failure.usr.id"] == USER_HASH assert "appsec.events.users.login.failure.email" not in meta assert "appsec.events.users.login.failure.username" not in meta - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_success_local(self): self.r_sdk_success = weblog.post( "/login?auth=local&sdk_event=success&sdk_user=sdkUser", - data={self.username_key: self.USER, self.password_key: self.PASSWORD}, + data=login_data(context, USER, PASSWORD), ) def test_login_sdk_success_local(self): assert self.r_sdk_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "anonymization" assert meta["_dd.appsec.events.users.login.success.sdk"] == "true" assert meta["appsec.events.users.login.success.track"] == "true" assert meta["usr.id"] == "sdkUser" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_success_basic(self): self.r_sdk_success = weblog.get( "/login?auth=basic&sdk_event=success&sdk_user=sdkUser", - headers={"Authorization": self.BASIC_AUTH_USER_HEADER}, + headers={"Authorization": BASIC_AUTH_USER_HEADER}, ) - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) + @missing_feature(context.library == "php", reason="Basic auth not implemented") def test_login_sdk_success_basic(self): assert self.r_sdk_success.status_code == 200 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_success): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_success): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "anonymization" assert meta["_dd.appsec.events.users.login.success.sdk"] == "true" assert meta["appsec.events.users.login.success.track"] == "true" assert meta["usr.id"] == "sdkUser" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_failure_basic(self): self.r_sdk_failure = weblog.get( "/login?auth=basic&sdk_event=failure&sdk_user=sdkUser&sdk_user_exists=true", - headers={"Authorization": "Basic aW52YWxpZFVzZXI6MTIzNA=="}, + headers={"Authorization": BASIC_AUTH_INVALID_USER_HEADER}, ) - @irrelevant( - context.library == "java", - reason="Basic auth makes insecure protocol test fail due to dedup, fixed in the next tracer release", - ) + @missing_feature(context.library == "php", reason="Basic auth not implemented") def test_login_sdk_failure_basic(self): assert self.r_sdk_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_failure): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "anonymization" assert meta["_dd.appsec.events.users.login.failure.sdk"] == "true" assert meta["appsec.events.users.login.failure.track"] == "true" assert meta["appsec.events.users.login.failure.usr.id"] == "sdkUser" assert meta["appsec.events.users.login.failure.usr.exists"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_sdk_failure_local(self): self.r_sdk_failure = weblog.post( "/login?auth=local&sdk_event=failure&sdk_user=sdkUser&sdk_user_exists=true", - data={self.username_key: "invalidUser", self.password_key: self.PASSWORD}, + data=login_data(context, INVALID_USER, PASSWORD), ) def test_login_sdk_failure_local(self): assert self.r_sdk_failure.status_code == 401 - for _, _, span in interfaces.library.get_spans(request=self.r_sdk_failure): + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_failure): meta = span.get("meta", {}) assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "anonymization" assert meta["_dd.appsec.events.users.login.failure.sdk"] == "true" assert meta["appsec.events.users.login.failure.track"] == "true" assert meta["appsec.events.users.login.failure.usr.id"] == "sdkUser" assert meta["appsec.events.users.login.failure.usr.exists"] == "true" - assert_priority(span, meta) + assert_priority(span, trace) def setup_login_success_headers(self): self.r_hdr_success = weblog.post( "/login?auth=local", - data={self.username_key: self.USER, self.password_key: self.PASSWORD}, - headers=self.HEADERS, + data=login_data(context, USER, PASSWORD), + headers=HEADERS, ) + @missing_feature(context.library < "dotnet@3.7.0") def test_login_success_headers(self): # Validate that all relevant headers are included on user login success on extended mode @@ -1195,7 +1090,7 @@ def validate_login_success_headers(span): if span.get("parent_id") not in (0, None): return - for header in self.HEADERS: + for header in HEADERS: assert f"http.request.headers.{header.lower()}" in span["meta"], f"Can't find {header} in span's meta" return True @@ -1204,10 +1099,11 @@ def validate_login_success_headers(span): def setup_login_failure_headers(self): self.r_hdr_failure = weblog.post( "/login?auth=local", - data={self.username_key: "invalidUser", self.password_key: self.PASSWORD}, - headers=self.HEADERS, + data=login_data(context, INVALID_USER, PASSWORD), + headers=HEADERS, ) + @missing_feature(context.library < "dotnet@3.7.0") def test_login_failure_headers(self): # Validate that all relevant headers are included on user login failure on extended mode @@ -1215,33 +1111,37 @@ def validate_login_failure_headers(span): if span.get("parent_id") not in (0, None): return - for header in self.HEADERS: + for header in HEADERS: assert f"http.request.headers.{header.lower()}" in span["meta"], f"Can't find {header} in span's meta" return True interfaces.library.validate_spans(self.r_hdr_failure, validate_login_failure_headers) -def assert_priority(span, meta): +def assert_priority(span, trace): MANUAL_KEEP_SAMPLING_PRIORITY = 2 - if span["metrics"].get("_sampling_priority_v1") != MANUAL_KEEP_SAMPLING_PRIORITY: - assert "manual.keep" in meta, "manual.keep should be in meta when _sampling_priority_v1 is not MANUAL_KEEP" - assert ( - meta["manual.keep"] == "true" - ), 'meta.manual.keep should be "true" when _sampling_priority_v1 is not MANUAL_KEEP' + if "_sampling_priority_v1" not in span["metrics"]: + # some tracers like java only send the priority in the first and last span of the trace + assert trace[0]["metrics"].get("_sampling_priority_v1") == MANUAL_KEEP_SAMPLING_PRIORITY + else: + assert span["metrics"].get("_sampling_priority_v1") == MANUAL_KEEP_SAMPLING_PRIORITY @rfc("https://docs.google.com/document/d/19VHLdJLVFwRb_JrE87fmlIM5CL5LdOBv4AmLxgdo9qI/edit") @features.user_monitoring @scenarios.appsec_auto_events_rc class Test_V2_Login_Events_RC: - - USER = "test" - PASSWORD = "1234" # ["disabled", "identification", "anonymization"] PAYLOADS = [ { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvQVNNX0ZFQVRVUkVTL2F1dG8tdXNlci1pbnN0cnVtL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJlZDRiNmZmNWRkMmQ3MWI5NjE0YjcxMzMwMTg4MjU2MmNmNGQ4ODk3YWRlMzIzYTZkMmQ5ZGViZDRhNzNhZDA0In0sImxlbmd0aCI6NTZ9fSwidmVyc2lvbiI6MX0sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6IjIyZDhlOTE0ZWM1NmE0MmQ4MTE4MmE4Y2RkODQyMTI0OTIyMDhlZDllNjRjZjQ2Mjg1ZTIxY2NjMjdhY2NhZDRlZDc3N2Y5MDkwNGVlYmZiODhiNDQ2ZGUxMGNkMjk1YzNjZDJlNjM1NmY4MjMzNDk5MzM1OTQ4YTRkMDI1ZTBkIn1dfQ==", + "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGl" + "PaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6e" + "yJkYXRhZG9nLzIvQVNNX0ZFQVRVUkVTL2F1dG8tdXNlci1pbnN0cnVtL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJ" + "zaGEyNTYiOiJlZDRiNmZmNWRkMmQ3MWI5NjE0YjcxMzMwMTg4MjU2MmNmNGQ4ODk3YWRlMzIzYTZkMmQ5ZGViZDRhNzNhZDA0In0sImxlb" + "md0aCI6NTZ9fSwidmVyc2lvbiI6MX0sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2I" + "xZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6IjIyZDhlOTE0ZWM1NmE0MmQ4MTE4MmE4Y2RkODQyMTI0OTIyMDhlZ" + "DllNjRjZjQ2Mjg1ZTIxY2NjMjdhY2NhZDRlZDc3N2Y5MDkwNGVlYmZiODhiNDQ2ZGUxMGNkMjk1YzNjZDJlNjM1NmY4MjMzNDk5MzM1OTQ" + "4YTRkMDI1ZTBkIn1dfQ==", "target_files": [ { "path": "datadog/2/ASM_FEATURES/auto-user-instrum/config", @@ -1251,7 +1151,14 @@ class Test_V2_Login_Events_RC: "client_configs": ["datadog/2/ASM_FEATURES/auto-user-instrum/config"], }, { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvQVNNX0ZFQVRVUkVTL2F1dG8tdXNlci1pbnN0cnVtL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6Mn0sImhhc2hlcyI6eyJzaGEyNTYiOiIyZWY2ZDVjMGZhNTQ4NTY0YTRjNWI3NTBjZmRkMDhkOWE4ODk2MmNhZTZkY2M5NDk0MjM4OWMxZDkwOTNkMTBhIn0sImxlbmd0aCI6NjJ9fSwidmVyc2lvbiI6Mn0sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6ImYzOTMxZDliODk4NWIzNTgxNjc1NWI4N2RjNmFmM2UxYzMzYWJmMjhjZDhkYzVmYWM2ZmMwMzgyZjNlMjUwOGU4ZmZmNzMxMDI2NWFhNDk3NjU2NjAyZDIxMTlhODFhNTViMjkwM2VkMjJlM2IzMzU0MmNhMWZiYmUxYWRhMjBhIn1dfQ==", + "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGl" + "PaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6e" + "yJkYXRhZG9nLzIvQVNNX0ZFQVRVUkVTL2F1dG8tdXNlci1pbnN0cnVtL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6Mn0sImhhc2hlcyI6eyJ" + "zaGEyNTYiOiIyZWY2ZDVjMGZhNTQ4NTY0YTRjNWI3NTBjZmRkMDhkOWE4ODk2MmNhZTZkY2M5NDk0MjM4OWMxZDkwOTNkMTBhIn0sImxlb" + "md0aCI6NjJ9fSwidmVyc2lvbiI6Mn0sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2I" + "xZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6ImYzOTMxZDliODk4NWIzNTgxNjc1NWI4N2RjNmFmM2UxYzMzYWJmM" + "jhjZDhkYzVmYWM2ZmMwMzgyZjNlMjUwOGU4ZmZmNzMxMDI2NWFhNDk3NjU2NjAyZDIxMTlhODFhNTViMjkwM2VkMjJlM2IzMzU0MmNhMWZ" + "iYmUxYWRhMjBhIn1dfQ==", "target_files": [ { "path": "datadog/2/ASM_FEATURES/auto-user-instrum/config", @@ -1261,7 +1168,14 @@ class Test_V2_Login_Events_RC: "client_configs": ["datadog/2/ASM_FEATURES/auto-user-instrum/config"], }, { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvQVNNX0ZFQVRVUkVTL2F1dG8tdXNlci1pbnN0cnVtL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6M30sImhhc2hlcyI6eyJzaGEyNTYiOiIwMjRiOGM4MmQxODBkZjc2NzMzNzVjYzYzZDdiYmRjMzRiNWE4YzE3NWQzNzE3ZGQwYjYyMzg2OTRhY2FiNWI3In0sImxlbmd0aCI6NjF9fSwidmVyc2lvbiI6M30sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6IjZlN2FkNDY1MDBiOGU0MTlkZDEyOTQyMjRiMGMzODM0OTZkZjc5OTJhOTliNDkwYWY0MmU1YjRkOTdjZWYxNTI3ZmRjNTAxMGVmYmI2NmYyY2VjMjgyY2Y4NzU5YmFlZThmOWY0ZjA4OWJjODJjNDk3NDUzYjc3YmM4Y2RiYTBkIn1dfQ==", + "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGl" + "PaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6e" + "yJkYXRhZG9nLzIvQVNNX0ZFQVRVUkVTL2F1dG8tdXNlci1pbnN0cnVtL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6M30sImhhc2hlcyI6eyJ" + "zaGEyNTYiOiIwMjRiOGM4MmQxODBkZjc2NzMzNzVjYzYzZDdiYmRjMzRiNWE4YzE3NWQzNzE3ZGQwYjYyMzg2OTRhY2FiNWI3In0sImxlb" + "md0aCI6NjF9fSwidmVyc2lvbiI6M30sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2I" + "xZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6IjZlN2FkNDY1MDBiOGU0MTlkZDEyOTQyMjRiMGMzODM0OTZkZjc5O" + "TJhOTliNDkwYWY0MmU1YjRkOTdjZWYxNTI3ZmRjNTAxMGVmYmI2NmYyY2VjMjgyY2Y4NzU5YmFlZThmOWY0ZjA4OWJjODJjNDk3NDUzYjc" + "3YmM4Y2RiYTBkIn1dfQ==", "target_files": [ { "path": "datadog/2/ASM_FEATURES/auto-user-instrum/config", @@ -1272,27 +1186,17 @@ class Test_V2_Login_Events_RC: }, ] - @property - def username_key(self): - """ In Rails the parametesr are group by scope. In the case of the test the scope is user. The syntax to group parameters in a POST request is scope[parameter] """ - return "user[username]" if "rails" in context.weblog_variant else "username" - - @property - def password_key(self): - """ In Rails the parametesr are group by scope. In the case of the test the scope is user. The syntax to group parameters in a POST request is scope[parameter] """ - return "user[password]" if "rails" in context.weblog_variant else "password" - def _send_rc_and_execute_request(self, rc_payload): - config_state = rc.send_command(raw_payload=rc_payload) - request = weblog.post( - "/login?auth=local", data={self.username_key: self.USER, self.password_key: self.PASSWORD} - ) - return {"config_state": config_state, "request": request} + config_states = rc.send_state(raw_payload=rc_payload) + request = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) + return {"config_states": config_states, "request": request} def _assert_response(self, test, validation): - config_state, request = test["config_state"], test["request"] - assert config_state["apply_state"] == rc.ApplyState.ACKNOWLEDGED, config_state + config_states, request = test["config_states"], test["request"] + + assert config_states[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED assert request.status_code == 200 + spans = [s for _, _, s in interfaces.library.get_spans(request=request)] assert spans, "No spans to validate" for span in spans: @@ -1315,3 +1219,772 @@ def validate_iden(meta): self._assert_response(self.tests[0], validate_disabled) self._assert_response(self.tests[1], validate_iden) self._assert_response(self.tests[2], validate_anon) + + +libs_without_user_id = ["java"] +libs_without_user_exist = ["nodejs", "java"] +libs_without_user_id_on_failure = ["nodejs", "java"] + + +@rfc("https://docs.google.com/document/d/1RT38U6dTTcB-8muiYV4-aVDCsT_XrliyakjtAPyjUpw") +@features.user_monitoring +@features.user_id_collection_modes +class Test_V3_Login_Events: + """ + Test login success/failure use cases + By default, mode is identification + """ + + # User entries in the internal DB: + # users = [ + # { + # id: 'social-security-id', + # username: 'test', + # password: '1234', + # email: 'testuser@ddog.com' + # }, + # { + # id: '591dc126-8431-4d0f-9509-b23318d3dce4', + # username: 'testuuid', + # password: '1234', + # email: 'testuseruuid@ddog.com' + # } + # ] + # + # These users can be created with signup events: + # users = [ + # { + # id: 'new-user', + # username: 'testnew', + # password: '1234', + # email: 'testnewuser@ddog.com' + # } + # ] + + def setup_login_success_local(self): + self.r_success = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) + + def test_login_success_local(self): + assert self.r_success.status_code == 200 + for _, trace, span in interfaces.library.get_spans(request=self.r_success): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.success.usr.login"] == USER + assert meta["_dd.appsec.usr.login"] == USER + assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "identification" + assert meta["appsec.events.users.login.success.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_id: + assert meta["usr.id"] == "social-security-id" + assert meta["_dd.appsec.usr.id"] == "social-security-id" + + def setup_login_success_basic(self): + self.r_success = weblog.get("/login?auth=basic", headers={"Authorization": BASIC_AUTH_USER_HEADER}) + + @missing_feature(context.library == "php", reason="Basic auth not implemented") + def test_login_success_basic(self): + assert self.r_success.status_code == 200 + for _, trace, span in interfaces.library.get_spans(request=self.r_success): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.success.usr.login"] == USER + assert meta["_dd.appsec.usr.login"] == USER + assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "identification" + assert meta["appsec.events.users.login.success.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_id: + assert meta["usr.id"] == "social-security-id" + assert meta["_dd.appsec.usr.id"] == "social-security-id" + + def setup_login_wrong_user_failure_local(self): + self.r_wrong_user_failure = weblog.post("/login?auth=local", data=login_data(context, INVALID_USER, PASSWORD)) + + def test_login_wrong_user_failure_local(self): + assert self.r_wrong_user_failure.status_code == 401 + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.failure.usr.login"] == INVALID_USER + assert meta["_dd.appsec.usr.login"] == INVALID_USER + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "identification" + assert meta["appsec.events.users.login.failure.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_exist: + assert meta["appsec.events.users.login.failure.usr.exists"] == "false" + + def setup_login_wrong_user_failure_basic(self): + self.r_wrong_user_failure = weblog.get( + "/login?auth=basic", headers={"Authorization": BASIC_AUTH_INVALID_USER_HEADER} + ) + + @missing_feature(context.library == "php", reason="Basic auth not implemented") + def test_login_wrong_user_failure_basic(self): + assert self.r_wrong_user_failure.status_code == 401 + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.failure.usr.login"] == INVALID_USER + assert meta["_dd.appsec.usr.login"] == INVALID_USER + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "identification" + assert meta["appsec.events.users.login.failure.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_exist: + assert meta["appsec.events.users.login.failure.usr.exists"] == "false" + + def setup_login_wrong_password_failure_local(self): + self.r_wrong_user_failure = weblog.post("/login?auth=local", data=login_data(context, USER, "12345")) + + def test_login_wrong_password_failure_local(self): + assert self.r_wrong_user_failure.status_code == 401 + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.failure.usr.login"] == USER + assert meta["_dd.appsec.usr.login"] == USER + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "identification" + assert meta["appsec.events.users.login.failure.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_exist: + assert meta["appsec.events.users.login.failure.usr.exists"] == "true" + + if context.library not in libs_without_user_id_on_failure: + assert meta["appsec.events.users.login.failure.usr.id"] == "social-security-id" + assert meta["_dd.appsec.usr.id"] == "social-security-id" + + def setup_login_wrong_password_failure_basic(self): + self.r_wrong_user_failure = weblog.get( + "/login?auth=basic", headers={"Authorization": BASIC_AUTH_INVALID_PASSWORD_HEADER} + ) + + @missing_feature(context.library == "php", reason="Basic auth not implemented") + def test_login_wrong_password_failure_basic(self): + assert self.r_wrong_user_failure.status_code == 401 + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.failure.usr.login"] == USER + assert meta["_dd.appsec.usr.login"] == USER + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "identification" + assert meta["appsec.events.users.login.failure.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_exist: + assert meta["appsec.events.users.login.failure.usr.exists"] == "true" + + if context.library not in libs_without_user_id_on_failure: + assert meta["appsec.events.users.login.failure.usr.id"] == "social-security-id" + assert meta["_dd.appsec.usr.id"] == "social-security-id" + + def setup_login_sdk_success_local(self): + self.r_sdk_success = weblog.post( + "/login?auth=local&sdk_event=success&sdk_user=sdkUser", + data=login_data(context, USER, PASSWORD), + ) + + def test_login_sdk_success_local(self): + assert self.r_sdk_success.status_code == 200 + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_success): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.success.usr.login"] == "sdkUser" + assert meta["_dd.appsec.usr.login"] == USER + assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "identification" + assert meta["appsec.events.users.login.success.track"] == "true" + assert meta["_dd.appsec.events.users.login.success.sdk"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_id: + assert meta["usr.id"] == "sdkUser" + assert meta["_dd.appsec.usr.id"] == "social-security-id" + + def setup_login_sdk_success_basic(self): + self.r_sdk_success = weblog.get( + "/login?auth=basic&sdk_event=success&sdk_user=sdkUser", + headers={"Authorization": BASIC_AUTH_USER_HEADER}, + ) + + @missing_feature(context.library == "php", reason="Basic auth not implemented") + def test_login_sdk_success_basic(self): + assert self.r_sdk_success.status_code == 200 + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_success): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.success.usr.login"] == "sdkUser" + assert meta["_dd.appsec.usr.login"] == USER + assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "identification" + assert meta["appsec.events.users.login.success.track"] == "true" + assert meta["_dd.appsec.events.users.login.success.sdk"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_id: + assert meta["usr.id"] == "sdkUser" + assert meta["_dd.appsec.usr.id"] == "social-security-id" + + def setup_login_sdk_failure_local(self): + self.r_sdk_failure = weblog.post( + "/login?auth=local&sdk_event=failure&sdk_user=sdkUser&sdk_user_exists=true", + data=login_data(context, INVALID_USER, PASSWORD), + ) + + def test_login_sdk_failure_local(self): + assert self.r_sdk_failure.status_code == 401 + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_failure): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.failure.usr.login"] == "sdkUser" + assert meta["_dd.appsec.usr.login"] == INVALID_USER + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "identification" + assert meta["appsec.events.users.login.failure.track"] == "true" + assert meta["_dd.appsec.events.users.login.failure.sdk"] == "true" + assert meta["appsec.events.users.login.failure.usr.exists"] == "true" + + def setup_login_sdk_failure_basic(self): + self.r_sdk_failure = weblog.get( + "/login?auth=basic&sdk_event=failure&sdk_user=sdkUser&sdk_user_exists=true", + headers={"Authorization": BASIC_AUTH_INVALID_USER_HEADER}, + ) + + @missing_feature(context.library == "php", reason="Basic auth not implemented") + def test_login_sdk_failure_basic(self): + assert self.r_sdk_failure.status_code == 401 + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_failure): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.failure.usr.login"] == "sdkUser" + assert meta["_dd.appsec.usr.login"] == INVALID_USER + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "identification" + assert meta["appsec.events.users.login.failure.track"] == "true" + assert meta["_dd.appsec.events.users.login.failure.sdk"] == "true" + assert meta["appsec.events.users.login.failure.usr.exists"] == "true" + + def setup_signup_local(self): + self.r_success = weblog.post("/signup", data=login_data(context, NEW_USER, PASSWORD)) + + @missing_feature(context.library == "nodejs", reason="Signup events not implemented") + def test_signup_local(self): + assert self.r_success.status_code == 200 + for _, trace, span in interfaces.library.get_spans(request=self.r_success): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.signup.usr.login"] == NEW_USER + assert meta["_dd.appsec.usr.login"] == NEW_USER + assert meta["_dd.appsec.events.users.signup.auto.mode"] == "identification" + assert meta["appsec.events.users.signup.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_id: + assert meta["appsec.events.users.signup.usr.id"] == "new-user" + assert meta["_dd.appsec.usr.id"] == "new-user" + + def setup_login_success_headers(self): + self.r_hdr_success = weblog.post( + "/login?auth=local", + data=login_data(context, USER, PASSWORD), + headers=HEADERS, + ) + + @missing_feature(context.library < "dotnet@3.7.0") + def test_login_success_headers(self): + # Validate that all relevant headers are included on user login success on extended mode + + def validate_login_success_headers(span): + if span.get("parent_id") not in (0, None): + return + + for header in HEADERS: + assert f"http.request.headers.{header.lower()}" in span["meta"], f"Can't find {header} in span's meta" + return True + + interfaces.library.validate_spans(self.r_hdr_success, validate_login_success_headers) + + def setup_login_failure_headers(self): + self.r_hdr_failure = weblog.post( + "/login?auth=local", + data=login_data(context, INVALID_USER, PASSWORD), + headers=HEADERS, + ) + + @missing_feature(context.library < "dotnet@3.7.0") + def test_login_failure_headers(self): + # Validate that all relevant headers are included on user login failure on extended mode + + def validate_login_failure_headers(span): + if span.get("parent_id") not in (0, None): + return + + for header in HEADERS: + assert f"http.request.headers.{header.lower()}" in span["meta"], f"Can't find {header} in span's meta" + return True + + interfaces.library.validate_spans(self.r_hdr_failure, validate_login_failure_headers) + + +@rfc("https://docs.google.com/document/d/1RT38U6dTTcB-8muiYV4-aVDCsT_XrliyakjtAPyjUpw") +@scenarios.appsec_auto_events_extended +@features.user_monitoring +@features.user_id_collection_modes +class Test_V3_Login_Events_Anon: + """Test login success/failure use cases + As default mode is identification, this scenario will test anonymization. + """ + + def setup_login_success_local(self): + self.r_success = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) + + def test_login_success_local(self): + assert self.r_success.status_code == 200 + for _, trace, span in interfaces.library.get_spans(request=self.r_success): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.success.usr.login"] == USERNAME_HASH + assert meta["_dd.appsec.usr.login"] == USERNAME_HASH + assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "anonymization" + assert meta["appsec.events.users.login.success.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_id: + assert meta["usr.id"] == USER_HASH + assert meta["_dd.appsec.usr.id"] == USER_HASH + + def setup_login_success_basic(self): + self.r_success = weblog.get("/login?auth=basic", headers={"Authorization": BASIC_AUTH_USER_HEADER}) + + @missing_feature(context.library == "php", reason="Basic auth not implemented") + def test_login_success_basic(self): + assert self.r_success.status_code == 200 + for _, trace, span in interfaces.library.get_spans(request=self.r_success): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.success.usr.login"] == USERNAME_HASH + assert meta["_dd.appsec.usr.login"] == USERNAME_HASH + assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "anonymization" + assert meta["appsec.events.users.login.success.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_id: + assert meta["usr.id"] == USER_HASH + assert meta["_dd.appsec.usr.id"] == USER_HASH + + def setup_login_wrong_user_failure_local(self): + self.r_wrong_user_failure = weblog.post("/login?auth=local", data=login_data(context, INVALID_USER, PASSWORD)) + + def test_login_wrong_user_failure_local(self): + assert self.r_wrong_user_failure.status_code == 401 + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.failure.usr.login"] == INVALID_USER_HASH + assert meta["_dd.appsec.usr.login"] == INVALID_USER_HASH + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "anonymization" + assert meta["appsec.events.users.login.failure.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_exist: + assert meta["appsec.events.users.login.failure.usr.exists"] == "false" + + def setup_login_wrong_user_failure_basic(self): + self.r_wrong_user_failure = weblog.get( + "/login?auth=basic", headers={"Authorization": BASIC_AUTH_INVALID_USER_HEADER} + ) + + @missing_feature(context.library == "php", reason="Basic auth not implemented") + def test_login_wrong_user_failure_basic(self): + assert self.r_wrong_user_failure.status_code == 401 + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.failure.usr.login"] == INVALID_USER_HASH + assert meta["_dd.appsec.usr.login"] == INVALID_USER_HASH + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "anonymization" + assert meta["appsec.events.users.login.failure.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_exist: + assert meta["appsec.events.users.login.failure.usr.exists"] == "false" + + def setup_login_wrong_password_failure_local(self): + self.r_wrong_user_failure = weblog.post("/login?auth=local", data=login_data(context, USER, "12345")) + + def test_login_wrong_password_failure_local(self): + assert self.r_wrong_user_failure.status_code == 401 + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.failure.usr.login"] == USERNAME_HASH + assert meta["_dd.appsec.usr.login"] == USERNAME_HASH + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "anonymization" + assert meta["appsec.events.users.login.failure.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_exist: + assert meta["appsec.events.users.login.failure.usr.exists"] == "true" + + if context.library not in libs_without_user_id_on_failure: + assert meta["appsec.events.users.login.failure.usr.id"] == USER_HASH + assert meta["_dd.appsec.usr.id"] == USER_HASH + + def setup_login_wrong_password_failure_basic(self): + self.r_wrong_user_failure = weblog.get( + "/login?auth=basic", headers={"Authorization": BASIC_AUTH_INVALID_PASSWORD_HEADER} + ) + + @missing_feature(context.library == "php", reason="Basic auth not implemented") + def test_login_wrong_password_failure_basic(self): + assert self.r_wrong_user_failure.status_code == 401 + for _, trace, span in interfaces.library.get_spans(request=self.r_wrong_user_failure): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.failure.usr.login"] == USERNAME_HASH + assert meta["_dd.appsec.usr.login"] == USERNAME_HASH + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "anonymization" + assert meta["appsec.events.users.login.failure.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_exist: + assert meta["appsec.events.users.login.failure.usr.exists"] == "true" + + if context.library not in libs_without_user_id_on_failure: + assert meta["appsec.events.users.login.failure.usr.id"] == USER_HASH + assert meta["_dd.appsec.usr.id"] == USER_HASH + + def setup_login_sdk_success_local(self): + self.r_sdk_success = weblog.post( + "/login?auth=local&sdk_event=success&sdk_user=sdkUser", + data=login_data(context, USER, PASSWORD), + ) + + def test_login_sdk_success_local(self): + assert self.r_sdk_success.status_code == 200 + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_success): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.success.usr.login"] == "sdkUser" + assert meta["_dd.appsec.usr.login"] == USERNAME_HASH + assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "anonymization" + assert meta["appsec.events.users.login.success.track"] == "true" + assert meta["_dd.appsec.events.users.login.success.sdk"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_id: + assert meta["usr.id"] == "sdkUser" + assert meta["_dd.appsec.usr.id"] == USER_HASH + + def setup_login_sdk_success_basic(self): + self.r_sdk_success = weblog.get( + "/login?auth=basic&sdk_event=success&sdk_user=sdkUser", + headers={"Authorization": BASIC_AUTH_USER_HEADER}, + ) + + @missing_feature(context.library == "php", reason="Basic auth not implemented") + def test_login_sdk_success_basic(self): + assert self.r_sdk_success.status_code == 200 + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_success): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.success.usr.login"] == "sdkUser" + assert meta["_dd.appsec.usr.login"] == USERNAME_HASH + assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "anonymization" + assert meta["appsec.events.users.login.success.track"] == "true" + assert meta["_dd.appsec.events.users.login.success.sdk"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_id: + assert meta["usr.id"] == "sdkUser" + assert meta["_dd.appsec.usr.id"] == USER_HASH + + def setup_login_sdk_failure_local(self): + self.r_sdk_failure = weblog.post( + "/login?auth=local&sdk_event=failure&sdk_user=sdkUser&sdk_user_exists=true", + data=login_data(context, INVALID_USER, PASSWORD), + ) + + def test_login_sdk_failure_local(self): + assert self.r_sdk_failure.status_code == 401 + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_failure): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.failure.usr.login"] == "sdkUser" + assert meta["_dd.appsec.usr.login"] == INVALID_USER_HASH + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "anonymization" + assert meta["appsec.events.users.login.failure.track"] == "true" + assert meta["_dd.appsec.events.users.login.failure.sdk"] == "true" + assert meta["appsec.events.users.login.failure.usr.exists"] == "true" + + def setup_login_sdk_failure_basic(self): + self.r_sdk_failure = weblog.get( + "/login?auth=basic&sdk_event=failure&sdk_user=sdkUser&sdk_user_exists=true", + headers={"Authorization": BASIC_AUTH_INVALID_USER_HEADER}, + ) + + @missing_feature(context.library == "php", reason="Basic auth not implemented") + def test_login_sdk_failure_basic(self): + assert self.r_sdk_failure.status_code == 401 + for _, trace, span in interfaces.library.get_spans(request=self.r_sdk_failure): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.login.failure.usr.login"] == "sdkUser" + assert meta["_dd.appsec.usr.login"] == INVALID_USER_HASH + assert meta["_dd.appsec.events.users.login.failure.auto.mode"] == "anonymization" + assert meta["appsec.events.users.login.failure.track"] == "true" + assert meta["_dd.appsec.events.users.login.failure.sdk"] == "true" + assert meta["appsec.events.users.login.failure.usr.exists"] == "true" + + def setup_signup_local(self): + self.r_success = weblog.post("/signup", data=login_data(context, NEW_USER, PASSWORD)) + + @missing_feature(context.library == "nodejs", reason="Signup events not implemented") + def test_signup_local(self): + assert self.r_success.status_code == 200 + for _, trace, span in interfaces.library.get_spans(request=self.r_success): + assert_priority(span, trace) + meta = span.get("meta", {}) + + # mandatory + assert meta["appsec.events.users.signup.usr.login"] == NEW_USERNAME_HASH + assert meta["_dd.appsec.usr.login"] == NEW_USERNAME_HASH + assert meta["_dd.appsec.events.users.signup.auto.mode"] == "anonymization" + assert meta["appsec.events.users.signup.track"] == "true" + + # optional (to review for each library) + if context.library not in libs_without_user_id: + assert meta["appsec.events.users.signup.usr.id"] == NEW_USER_HASH + assert meta["_dd.appsec.usr.id"] == NEW_USER_HASH + + +DISABLED = ("datadog/2/ASM_FEATURES/auto-user-instrum/config", {"auto_user_instrum": {"mode": "disabled"}}) +IDENTIFICATION = ("datadog/2/ASM_FEATURES/auto-user-instrum/config", {"auto_user_instrum": {"mode": "identification"}}) +ANONYMIZATION = ("datadog/2/ASM_FEATURES/auto-user-instrum/config", {"auto_user_instrum": {"mode": "anonymization"}}) + + +@rfc("https://docs.google.com/document/d/1RT38U6dTTcB-8muiYV4-aVDCsT_XrliyakjtAPyjUpw") +@features.user_monitoring +@scenarios.appsec_auto_events_rc +class Test_V3_Login_Events_RC: + def _send_rc_and_execute_request(self, config): + config_state = rc.rc_state.set_config(*config).apply() + request = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) + return {"config_state": config_state, "request": request} + + def _assert_response(self, test, validation): + config_state, request = test["config_state"], test["request"] + + assert config_state[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert request.status_code == 200 + + spans = [s for _, _, s in interfaces.library.get_spans(request=request)] + assert spans, "No spans to validate" + for span in spans: + meta = span.get("meta", {}) + validation(meta) + + def setup_rc(self): + self.disabled = self._send_rc_and_execute_request(DISABLED) + self.identification = self._send_rc_and_execute_request(IDENTIFICATION) + self.anonymization = self._send_rc_and_execute_request(ANONYMIZATION) + + def test_rc(self): + def validate_disabled(meta): + assert "_dd.appsec.events.users.login.success.auto.mode" not in meta + + def validate_anon(meta): + assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "anonymization" + + def validate_iden(meta): + assert meta["_dd.appsec.events.users.login.success.auto.mode"] == "identification" + + self._assert_response(self.disabled, validate_disabled) + self._assert_response(self.identification, validate_iden) + self._assert_response(self.anonymization, validate_anon) + + +CONFIG_ENABLED = ( + "datadog/2/ASM_FEATURES/asm_features_activation/config", + {"asm": {"enabled": True}}, +) + +BLOCK_USER_RULE = ( + "datadog/2/ASM_DD/rules/config", + { + "version": "2.1", + "metadata": {"rules_version": "1.2.6"}, + "rules": [ + { + "id": "block-user-id", + "name": "Block User IDs", + "tags": {"type": "block_user", "category": "security_response"}, + "conditions": [ + { + "parameters": {"inputs": [{"address": "usr.id"}], "data": "blocked_user_id"}, + "operator": "exact_match", + } + ], + "transformers": [], + "on_match": ["block"], + }, + { + "id": "block-user-login", + "name": "Block User Logins", + "tags": {"type": "block_user", "category": "security_response"}, + "conditions": [ + { + "parameters": {"inputs": [{"address": "usr.login"}], "data": "blocked_user_login"}, + "operator": "exact_match", + } + ], + "transformers": [], + "on_match": ["block"], + }, + ], + }, +) + +BLOCK_USER_ID = ( + "datadog/2/ASM_DATA/blocked_user_id/config", + { + "rules_data": [ + { + "id": "blocked_user_id", + "type": "data_with_expiration", + "data": [{"value": "social-security-id", "expiration": 0}, {"value": "sdkUser", "expiration": 0}], + }, + ], + }, +) + +BLOCK_USER_LOGIN = ( + "datadog/2/ASM_DATA/blocked_user_login/config", + { + "rules_data": [ + { + "id": "blocked_user_login", + "type": "data_with_expiration", + "data": [{"value": "test", "expiration": 0}, {"value": "sdkUser", "expiration": 0}], + }, + ], + }, +) + + +@rfc("https://docs.google.com/document/d/1RT38U6dTTcB-8muiYV4-aVDCsT_XrliyakjtAPyjUpw") +@features.user_monitoring +@scenarios.appsec_runtime_activation +class Test_V3_Login_Events_Blocking: + def setup_login_event_blocking_auto_id(self): + rc.rc_state.reset().apply() + + self.config_state_1 = rc.rc_state.set_config(*CONFIG_ENABLED).apply() + self.r_login = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) + + self.config_state_2 = rc.rc_state.set_config(*BLOCK_USER_RULE).apply() + self.config_state_3 = rc.rc_state.set_config(*BLOCK_USER_ID).apply() + self.r_login_blocked = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) + + def test_login_event_blocking_auto_id(self): + assert self.config_state_1[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.r_login.status_code == 200 + + assert self.config_state_2[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.config_state_3[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + if context.library not in libs_without_user_id: + interfaces.library.assert_waf_attack(self.r_login_blocked, rule="block-user-id") + assert self.r_login_blocked.status_code == 403 + + def setup_login_event_blocking_auto_login(self): + rc.rc_state.reset().apply() + + self.config_state_1 = rc.rc_state.set_config(*CONFIG_ENABLED).apply() + self.r_login = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) + + self.config_state_2 = rc.rc_state.set_config(*BLOCK_USER_RULE).apply() + self.config_state_3 = rc.rc_state.set_config(*BLOCK_USER_LOGIN).apply() + self.r_login_blocked = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) + + def test_login_event_blocking_auto_login(self): + assert self.config_state_1[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.r_login.status_code == 200 + + assert self.config_state_2[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.config_state_3[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + interfaces.library.assert_waf_attack(self.r_login_blocked, rule="block-user-login") + assert self.r_login_blocked.status_code == 403 + + def setup_login_event_blocking_sdk(self): + rc.rc_state.reset().apply() + + self.config_state_1 = rc.rc_state.set_config(*CONFIG_ENABLED).apply() + self.r_login = weblog.post( + "/login?auth=local&sdk_event=success&sdk_user=sdkUser", data=login_data(context, UUID_USER, PASSWORD) + ) + + self.config_state_2 = rc.rc_state.set_config(*BLOCK_USER_RULE).apply() + self.config_state_3 = rc.rc_state.set_config(*BLOCK_USER_ID).apply() + self.r_login_blocked = weblog.post( + "/login?auth=local&sdk_event=success&sdk_user=sdkUser", data=login_data(context, UUID_USER, PASSWORD) + ) + + @missing_feature(context.library == "nodejs", reason="SDK blocking not implemented") + def test_login_event_blocking_sdk(self): + assert self.config_state_1[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.r_login.status_code == 200 + + assert self.config_state_2[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.config_state_3[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + interfaces.library.assert_waf_attack(self.r_login_blocked, rule="block-user-id") + assert self.r_login_blocked.status_code == 403 + + +@rfc("https://docs.google.com/document/d/1RT38U6dTTcB-8muiYV4-aVDCsT_XrliyakjtAPyjUpw") +@features.user_monitoring +@scenarios.remote_config_mocked_backend_asm_dd +class Test_V3_Auto_User_Instrum_Mode_Capability: + """Validate that ASM_AUTO_USER_INSTRUM_MODE (31) capability is sent""" + + def test_capability_auto_user_instrum_mode(self): + interfaces.library.assert_rc_capability(Capabilities.ASM_AUTO_USER_INSTRUM_MODE) diff --git a/tests/appsec/test_automated_user_and_session_tracking.py b/tests/appsec/test_automated_user_and_session_tracking.py new file mode 100644 index 00000000000..1f0de5d2fcc --- /dev/null +++ b/tests/appsec/test_automated_user_and_session_tracking.py @@ -0,0 +1,240 @@ +# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. +# This product includes software developed at Datadog (https://www.datadoghq.com/). +# Copyright 2024 Datadog, Inc. + +from utils import context +from utils import features +from utils import interfaces +from utils import remote_config as rc +from utils import rfc +from utils import scenarios +from utils import weblog + +# User entries in the internal DB: +# users = [ +# { +# id: 'social-security-id', +# username: 'test', +# password: '1234', +# email: 'testuser@ddog.com' +# }, +# { +# id: '591dc126-8431-4d0f-9509-b23318d3dce4', +# username: 'testuuid', +# password: '1234', +# email: 'testuseruuid@ddog.com' +# } +# ] +USER = "test" +UUID_USER = "testuuid" +PASSWORD = "1234" + +libs_without_user_id = ["java"] + + +def login_data(context, user, password): + """In Rails the parameters are group by scope. In the case of the test the scope is user. + The syntax to group parameters in a POST request is scope[parameter] + """ + username_key = "user[username]" if "rails" in context.weblog_variant else "username" + password_key = "user[password]" if "rails" in context.weblog_variant else "password" + return {username_key: user, password_key: password} + + +@rfc("https://docs.google.com/document/d/1RT38U6dTTcB-8muiYV4-aVDCsT_XrliyakjtAPyjUpw") +@features.user_monitoring +class Test_Automated_User_Tracking: + def setup_user_tracking_auto(self): + self.r_login = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) + self.r_home = weblog.get( + "/", + cookies=self.r_login.cookies, + ) + + def test_user_tracking_auto(self): + assert self.r_login.status_code == 200 + + assert self.r_home.status_code == 200 + for _, _, span in interfaces.library.get_spans(request=self.r_home): + meta = span.get("meta", {}) + if context.library in libs_without_user_id: + assert meta["usr.id"] == USER + assert meta["_dd.appsec.usr.id"] == USER + else: + assert meta["usr.id"] == "social-security-id" + assert meta["_dd.appsec.usr.id"] == "social-security-id" + + assert meta["_dd.appsec.user.collection_mode"] == "identification" + + def setup_user_tracking_sdk_overwrite(self): + self.r_login = weblog.post( + "/login?auth=local&sdk_event=success&sdk_user=sdkUser", data=login_data(context, USER, PASSWORD) + ) + + def test_user_tracking_sdk_overwrite(self): + assert self.r_login.status_code == 200 + for _, _, span in interfaces.library.get_spans(request=self.r_login): + meta = span.get("meta", {}) + assert meta["usr.id"] == "sdkUser" + if context.library in libs_without_user_id: + assert meta["_dd.appsec.usr.id"] == USER + else: + assert meta["_dd.appsec.usr.id"] == "social-security-id" + + assert meta["_dd.appsec.user.collection_mode"] == "sdk" + + +CONFIG_ENABLED = ( + "datadog/2/ASM_FEATURES/asm_features_activation/config", + {"asm": {"enabled": True}}, +) + +BLOCK_USER = ( + "datadog/2/ASM_DD/rules/config", + { + "version": "2.1", + "metadata": {"rules_version": "1.2.6"}, + "rules": [ + { + "id": "block-users", + "name": "Block User Addresses", + "tags": {"type": "block_user", "category": "security_response"}, + "conditions": [ + { + "parameters": {"inputs": [{"address": "usr.id"}], "data": "blocked_users"}, + "operator": "exact_match", + } + ], + "transformers": [], + "on_match": ["block"], + } + ], + }, +) + +BLOCK_USER_DATA = ( + "datadog/2/ASM_DATA/blocked_users/config", + { + "rules_data": [ + { + "id": "blocked_users", + "type": "data_with_expiration", + "data": [ + {"value": "test", "expiration": 0}, + {"value": "social-security-id", "expiration": 0}, + {"value": "sdkUser", "expiration": 0}, + ], + }, + ], + }, +) + + +@rfc("https://docs.google.com/document/d/1RT38U6dTTcB-8muiYV4-aVDCsT_XrliyakjtAPyjUpw") +@features.user_monitoring +@scenarios.appsec_runtime_activation +class Test_Automated_User_Blocking: + def setup_user_blocking_auto(self): + rc.rc_state.reset().apply() + + self.config_state_1 = rc.rc_state.set_config(*CONFIG_ENABLED).apply() + self.r_login = weblog.post("/login?auth=local", data=login_data(context, USER, PASSWORD)) + + self.config_state_2 = rc.rc_state.set_config(*BLOCK_USER).apply() + self.config_state_3 = rc.rc_state.set_config(*BLOCK_USER_DATA).apply() + self.r_home_blocked = weblog.get( + "/", + cookies=self.r_login.cookies, + ) + + def test_user_blocking_auto(self): + assert self.config_state_1[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.r_login.status_code == 200 + + assert self.config_state_2[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.config_state_3[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + interfaces.library.assert_waf_attack(self.r_home_blocked, rule="block-users") + assert self.r_home_blocked.status_code == 403 + + def setup_user_blocking_sdk(self): + rc.rc_state.reset().apply() + + self.config_state_1 = rc.rc_state.set_config(*CONFIG_ENABLED).apply() + self.config_state_2 = rc.rc_state.set_config(*BLOCK_USER).apply() + self.config_state_3 = rc.rc_state.set_config(*BLOCK_USER_DATA).apply() + self.r_login = weblog.post("/login?auth=local", data=login_data(context, UUID_USER, PASSWORD)) + self.r_login_blocked = weblog.post( + "/login?auth=local&sdk_event=success&sdk_user=sdkUser", data=login_data(context, UUID_USER, PASSWORD) + ) + + def test_user_blocking_sdk(self): + assert self.config_state_1[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.config_state_2[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.config_state_3[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + + assert self.r_login.status_code == 200 + + interfaces.library.assert_waf_attack(self.r_login_blocked, rule="block-users") + assert self.r_login_blocked.status_code == 403 + + +BLOCK_SESSION = ( + "datadog/2/ASM_DD/rules/config", + { + "version": "2.1", + "metadata": {"rules_version": "1.2.6"}, + "rules": [ + { + "id": "block-sessions", + "name": "Block Session Addresses", + "tags": {"type": "block_user", "category": "security_response"}, + "conditions": [ + { + "parameters": {"inputs": [{"address": "usr.session_id"}], "data": "blocked_sessions"}, + "operator": "exact_match", + } + ], + "transformers": [], + "on_match": ["block"], + } + ], + }, +) + +BLOCK_SESSION_DATA = ( + "datadog/2/ASM_DATA/blocked_sessions/config", + { + "rules_data": [ + {"id": "blocked_sessions", "type": "data_with_expiration", "data": []}, + ], + }, +) + + +@rfc("https://docs.google.com/document/d/1RT38U6dTTcB-8muiYV4-aVDCsT_XrliyakjtAPyjUpw") +@features.user_monitoring +@scenarios.appsec_runtime_activation +class Test_Automated_Session_Blocking: + def setup_session_blocking(self): + rc.rc_state.reset().apply() + + self.config_state_1 = rc.rc_state.set_config(*CONFIG_ENABLED).apply() + self.r_create_session = weblog.get("/session/new") + self.session_id = self.r_create_session.text + + BLOCK_SESSION_DATA[1]["rules_data"][0]["data"].append({"value": self.session_id, "expiration": 0}) + self.config_state_2 = rc.rc_state.set_config(*BLOCK_SESSION).apply() + self.config_state_3 = rc.rc_state.set_config(*BLOCK_SESSION_DATA).apply() + self.r_home_blocked = weblog.get( + "/", + cookies=self.r_create_session.cookies, + ) + + def test_session_blocking(self): + assert self.config_state_1[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.r_create_session.status_code == 200 + + assert self.config_state_2[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + assert self.config_state_3[rc.RC_STATE] == rc.ApplyState.ACKNOWLEDGED + interfaces.library.assert_waf_attack(self.r_home_blocked, pattern=self.session_id, rule="block-sessions") + assert self.r_home_blocked.status_code == 403 diff --git a/tests/appsec/test_blocking_addresses.py b/tests/appsec/test_blocking_addresses.py index ca12e3ca176..ac6fa514318 100644 --- a/tests/appsec/test_blocking_addresses.py +++ b/tests/appsec/test_blocking_addresses.py @@ -17,194 +17,6 @@ ) -@scenarios.appsec_blocking -@features.appsec_request_blocking -class Test_BlockingAddresses: - """Test the addresses supported for blocking""" - - def setup_block_ip(self): - self.block_ip_req = weblog.get(headers={"X-Forwarded-For": "1.1.1.1"}) - - def test_block_ip(self): - """can block the request forwarded for the ip""" - - assert self.block_ip_req.status_code == 403 - - def setup_block_user(self): - self.block_user_req = weblog.get("/users", params={"user": "blockedUser"}) - - @missing_feature(library="java", reason="Missing /users endpoint") - @missing_feature(weblog_variant="nextjs", reason="Not supported yet") - def test_block_user(self): - """can block the request from the user""" - - assert self.block_user_req.status_code == 403 - - def setup_request_method(self): - self.rm_req = weblog.request("OPTIONS") - - @missing_feature(context.library < "ruby@1.12.0") - def test_request_method(self): - """can block on server.request.method""" - - interfaces.library.assert_waf_attack(self.rm_req, rule="tst-037-006") - assert self.rm_req.status_code == 403 - - def setup_request_uri(self): - self.ruri_req = weblog.get("/waf/foo.git") - - def test_request_uri(self): - """can block on server.request.uri.raw""" - - interfaces.library.assert_waf_attack(self.ruri_req, rule="tst-037-002") - assert self.ruri_req.status_code == 403 - - def setup_path_params(self): - self.pp_req = weblog.get("/params/AiKfOeRcvG45") - - @missing_feature( - context.library < "java@1.15.0", reason="When supported, path parameter detection happens on subsequent WAF run" - ) - @missing_feature(library="nodejs", reason="Not supported yet") - @missing_feature( - context.library == "java" and context.weblog_variant == "akka-http", reason="path parameters not supported" - ) - @bug(weblog_variant="spring-boot-payara", reason="APPSEC-52335") - @irrelevant(context.library == "ruby" and context.weblog_variant == "rack") - @irrelevant(context.library == "golang" and context.weblog_variant == "net-http") - def test_path_params(self): - """can block on server.request.path_params""" - - interfaces.library.assert_waf_attack(self.pp_req, rule="tst-037-007") - assert self.pp_req.status_code == 403 - - def setup_request_query(self): - self.rq_req = weblog.get("/waf", params={"foo": "xtrace"}) - - @missing_feature(weblog_variant="nextjs", reason="Not supported yet") - def test_request_query(self): - """can block on server.request.query""" - - interfaces.library.assert_waf_attack(self.rq_req, rule="tst-037-001") - assert self.rq_req.status_code == 403 - - def setup_cookies(self): - self.c_req = weblog.get("/", headers={"Cookie": "mycookie=jdfoSDGFkivRG_234"}) - - @missing_feature(context.library < "nodejs@4.16.0", reason="Not supported yet") - @missing_feature(weblog_variant="nextjs", reason="Not supported yet") - def test_cookies(self): - """can block on server.request.cookies""" - - interfaces.library.assert_waf_attack(self.c_req, rule="tst-037-008") - assert self.c_req.status_code == 403 - - def setup_request_body_urlencoded(self): - self.rbue_req = weblog.post("/waf", data={"foo": "bsldhkuqwgervf"}) - - @missing_feature(context.library < "java@1.15.0", reason="Happens on a subsequent WAF run") - @missing_feature(weblog_variant="nextjs", reason="Not supported yet") - @bug(weblog_variant="spring-boot-payara", reason="Not blocking") - @irrelevant(context.library == "golang", reason="Body blocking happens through SDK") - def test_request_body_urlencoded(self): - """can block on server.request.body (urlencoded variant)""" - - interfaces.library.assert_waf_attack(self.rbue_req, rule="tst-037-004") - assert self.rbue_req.status_code == 403 - - def setup_request_body_multipart(self): - self.rbmp_req = weblog.post("/waf", files={"foo": (None, "bsldhkuqwgervf")}) - - @missing_feature(context.library == "dotnet", reason="Don't support multipart yet") - @missing_feature(context.library == "php", reason="Don't support multipart yet") - @missing_feature(context.library < "java@1.15.0", reason="Happens on a subsequent WAF run") - @missing_feature(library="nodejs", reason="Not supported yet") - @missing_feature( - context.weblog_variant - in ( - "spring-boot-jetty", - "spring-boot-undertow", - "spring-boot-openliberty", - "spring-boot-payara", - "jersey-grizzly2", - "resteasy-netty3", - "ratpack", - ), - reason="Blocking on multipart not supported yet", - ) - @irrelevant(context.library == "golang", reason="Body blocking happens through SDK") - def test_request_body_multipart(self): - """can block on server.request.body (multipart/form-data variant)""" - - interfaces.library.assert_waf_attack(self.rbmp_req, rule="tst-037-004") - assert self.rbmp_req.status_code == 403 - - def setup_response_status(self): - self.rss_req = weblog.get(path="/status", params={"code": "418"}) - - @missing_feature(context.library < "dotnet@2.32.0") - @missing_feature(context.library < "java@1.18.0" and context.weblog_variant in ("spring-boot", "uds-spring-boot")) - @missing_feature( - context.library < "java@1.19.0" - and context.weblog_variant in ("spring-boot-jetty", "spring-boot-undertow", "spring-boot-wildfly") - ) - @missing_feature( - context.library == "java" - and context.weblog_variant - not in ( - "akka-http", - "play", - "spring-boot", - "uds-spring-boot", - "spring-boot-jetty", - "spring-boot-undertow", - "spring-boot-wildfly", - ) - ) - @missing_feature(context.library == "golang", reason="No blocking on server.response.*") - @missing_feature(context.library < "ruby@1.10.0") - @missing_feature(context.library < "nodejs@5.17.0", reason="Not supported yet") - def test_response_status(self): - """can block on server.response.status""" - - interfaces.library.assert_waf_attack(self.rss_req, rule="tst-037-005") - assert self.rss_req.status_code == 403 - - def setup_not_found(self): - self.rnf_req = weblog.get(path="/finger_print") - - @missing_feature( - context.library == "java" and context.weblog_variant not in ("akka-http", "play"), - reason="Happens on a subsequent WAF run", - ) - @missing_feature(context.library == "ruby", reason="Not working") - @missing_feature(context.library < "nodejs@5.17.0", reason="Not supported yet") - @missing_feature(context.library == "golang", reason="No blocking on server.response.*") - def test_not_found(self): - """can block on server.response.status""" - - interfaces.library.assert_waf_attack(self.rnf_req, rule="tst-037-010") - assert self.rnf_req.status_code == 403 - - def setup_response_header(self): - self.rsh_req = weblog.get(path="/headers") - - @missing_feature(context.library < "dotnet@2.32.0") - @missing_feature( - context.library == "java" and context.weblog_variant not in ("akka-http", "play"), - reason="Happens on a subsequent WAF run", - ) - @missing_feature(context.library == "ruby") - @missing_feature(context.library == "php", reason="Headers already sent at this stage") - @missing_feature(context.library < "nodejs@5.17.0", reason="Not supported yet") - @missing_feature(context.library == "golang", reason="No blocking on server.response.*") - def test_response_header(self): - """can block on server.response.headers.no_cookies""" - - interfaces.library.assert_waf_attack(self.rsh_req, rule="tst-037-009") - assert self.rsh_req.status_code == 403 - - def _assert_custom_event_tag_presence(expected_value): def wrapper(span): tag = "appsec.events.system_tests_appsec_event.value" @@ -225,10 +37,49 @@ def wrapper(span): return wrapper +@scenarios.appsec_blocking +@features.appsec_request_blocking +class Test_Blocking_client_ip: + """Test if blocking is supported on http.client_ip address""" + + def setup_blocking(self): + self.rm_req_block = weblog.get(headers={"X-Forwarded-For": "1.1.1.1"}) + + def test_blocking(self): + """can block the request forwarded for the ip""" + + assert self.rm_req_block.status_code == 403 + interfaces.library.assert_waf_attack(self.rm_req_block, rule="blk-001-001") + + def setup_blocking_before(self): + self.block_req2 = weblog.get("/tag_value/tainted_value_6512/200", headers={"X-Forwarded-For": "1.1.1.1"}) + + def test_blocking_before(self): + """Test that blocked requests are blocked before being processed""" + # second request should block and must not set the tag in span + assert self.block_req2.status_code == 403 + interfaces.library.assert_waf_attack(self.block_req2, rule="blk-001-001") + interfaces.library.validate_spans(self.block_req2, _assert_custom_event_tag_absence()) + + +@scenarios.appsec_blocking +@features.appsec_request_blocking +class Test_Blocking_user_id: + """Test if blocking is supported on usr.id address""" + + def setup_block_user(self): + self.rm_req_block = weblog.get("/users", params={"user": "blockedUser"}) + + def test_block_user(self): + """can block the request from the user""" + + assert self.rm_req_block.status_code == 403 + interfaces.library.assert_waf_attack(self.rm_req_block, rule="block-users") + + @rfc("https://datadoghq.atlassian.net/wiki/spaces/APS/pages/2667021177/Suspicious+requests+blocking") @scenarios.appsec_blocking @features.appsec_request_blocking -@bug(context.library >= "java@1.20.0" and context.weblog_variant == "spring-boot-openliberty") class Test_Blocking_request_method: """Test if blocking is supported on server.request.method address""" @@ -254,7 +105,7 @@ def setup_blocking_before(self): self.set_req1 = weblog.request("GET", path="/tag_value/clean_value_3876/200") self.block_req2 = weblog.request("OPTIONS", path="/tag_value/tainted_value_6512/200") - @flaky(context.library < "java@1.16.0") + @flaky(context.library < "java@1.16.0", reason="APMRP-360") def test_blocking_before(self): """Test that blocked requests are blocked before being processed""" # first request should not block and must set the tag in span accordingly @@ -270,7 +121,6 @@ def test_blocking_before(self): @rfc("https://datadoghq.atlassian.net/wiki/spaces/APS/pages/2667021177/Suspicious+requests+blocking") @scenarios.appsec_blocking @features.appsec_request_blocking -@bug(context.library >= "java@1.20.0" and context.weblog_variant == "spring-boot-openliberty") class Test_Blocking_request_uri: """Test if blocking is supported on server.request.uri.raw address""" @@ -299,7 +149,7 @@ def test_non_blocking(self): def setup_blocking_uri_raw(self): self.rm_req_uri_raw = weblog.get("/waf/uri_raw_should_not_include_scheme_domain_and_port") - @bug(context.library < "dotnet@2.50.0", reason="dotnet may include scheme, domain and port in uri.raw") + @bug(context.library < "dotnet@2.50.0", reason="APMRP-360") def test_blocking_uri_raw(self): interfaces.library.assert_waf_attack(self.rm_req_uri_raw, rule="tst-037-011") assert self.rm_req_uri_raw.status_code == 403 @@ -323,7 +173,6 @@ def test_blocking_before(self): @rfc("https://datadoghq.atlassian.net/wiki/spaces/APS/pages/2667021177/Suspicious+requests+blocking") @scenarios.appsec_blocking @features.appsec_request_blocking -@bug(context.library >= "java@1.20.0" and context.weblog_variant == "spring-boot-openliberty") class Test_Blocking_request_path_params: """Test if blocking is supported on server.request.path_params address""" @@ -368,7 +217,6 @@ def test_blocking_before(self): @rfc("https://datadoghq.atlassian.net/wiki/spaces/APS/pages/2667021177/Suspicious+requests+blocking") @scenarios.appsec_blocking @features.appsec_request_blocking -@bug(context.library >= "java@1.20.0" and context.weblog_variant == "spring-boot-openliberty") class Test_Blocking_request_query: """Test if blocking is supported on server.request.query address""" @@ -416,7 +264,6 @@ def test_blocking_before(self): @rfc("https://datadoghq.atlassian.net/wiki/spaces/APS/pages/2667021177/Suspicious+requests+blocking") @scenarios.appsec_blocking @features.appsec_request_blocking -@bug(context.library >= "java@1.20.0" and context.weblog_variant == "spring-boot-openliberty") class Test_Blocking_request_headers: """Test if blocking is supported on server.request.headers.no_cookies address""" @@ -464,7 +311,6 @@ def test_blocking_before(self): @rfc("https://datadoghq.atlassian.net/wiki/spaces/APS/pages/2667021177/Suspicious+requests+blocking") @scenarios.appsec_blocking @features.appsec_request_blocking -@bug(context.library >= "java@1.20.0" and context.weblog_variant == "spring-boot-openliberty") class Test_Blocking_request_cookies: """Test if blocking is supported on server.request.cookies address""" @@ -512,7 +358,6 @@ def test_blocking_before(self): @rfc("https://datadoghq.atlassian.net/wiki/spaces/APS/pages/2667021177/Suspicious+requests+blocking") @scenarios.appsec_blocking @features.appsec_request_blocking -@bug(context.library >= "java@1.20.0" and context.weblog_variant == "spring-boot-openliberty") class Test_Blocking_request_body: """Test if blocking is supported on server.request.body address for urlencoded body""" @@ -532,7 +377,7 @@ def setup_non_blocking(self): self.setup_blocking() # raw body are never parsed self.rm_req_nonblock1 = weblog.post( - "/waf", data=b'\x00{"value3": "bsldhkuqwgervf"}\xFF', headers={"content-type": "application/octet-stream"} + "/waf", data=b'\x00{"value3": "bsldhkuqwgervf"}\xff', headers={"content-type": "application/octet-stream"} ) self.rm_req_nonblock2 = weblog.post("/waf", data={"good": "value"}) @@ -574,6 +419,21 @@ def test_blocking_before(self): interfaces.library.validate_spans(self.block_req2, _assert_custom_event_tag_absence()) +@scenarios.appsec_blocking +@features.appsec_request_blocking +class Test_Blocking_request_body_multipart: + """Test if blocking is supported on server.request.body address for multipart body""" + + def setup_blocking(self): + self.rbmp_req = weblog.post("/waf", files={"foo": (None, "bsldhkuqwgervf")}) + + def test_blocking(self): + """can block on server.request.body (multipart/form-data variant)""" + + interfaces.library.assert_waf_attack(self.rbmp_req, rule="tst-037-004") + assert self.rbmp_req.status_code == 403 + + @rfc("https://datadoghq.atlassian.net/wiki/spaces/APS/pages/2667021177/Suspicious+requests+blocking") @scenarios.appsec_blocking @features.appsec_response_blocking @@ -586,19 +446,35 @@ def setup_blocking(self): def test_blocking(self): """Test if requests that should be blocked are blocked""" - for code, response in self.rm_req_block.items(): + for response in self.rm_req_block.values(): assert response.status_code == 403, response.request.url interfaces.library.assert_waf_attack(response, rule="tst-037-005") def setup_non_blocking(self): self.setup_blocking() - self.rm_req_nonblock = {status: weblog.get(f"/tag_value/anything/{status}") for status in (411, 412, 413, 414)} + self.rm_req_nonblock = { + str(status): weblog.get(f"/tag_value/anything/{status}") for status in (411, 412, 413, 414) + } def test_non_blocking(self): """Test if requests that should not be blocked are not blocked""" self.test_blocking() for code, response in self.rm_req_nonblock.items(): - assert response.status_code == code, response.request.url + assert str(response.status_code) == code, response.request.url + + def setup_not_found(self): + self.rnf_req = weblog.get(path="/finger_print") + + @missing_feature( + context.library == "java" and context.weblog_variant not in ("akka-http", "play"), + reason="Happens on a subsequent WAF run", + ) + @missing_feature(context.library == "golang", reason="No blocking on server.response.*") + def test_not_found(self): + """can block on server.response.status""" + + interfaces.library.assert_waf_attack(self.rnf_req, rule="tst-037-010") + assert self.rnf_req.status_code == 403 @rfc("https://datadoghq.atlassian.net/wiki/spaces/APS/pages/2667021177/Suspicious+requests+blocking") @@ -609,7 +485,7 @@ class Test_Blocking_response_headers: def setup_blocking(self): if not hasattr(self, "rm_req_block1") or self.rm_req_block1 is None: - self.rm_req_block1 = weblog.get(f"/tag_value/anything/200?content-language=en-us") + self.rm_req_block1 = weblog.get(f"/tag_value/anything/200?content-language=fo-fo") if not hasattr(self, "rm_req_block2") or self.rm_req_block2 is None: self.rm_req_block2 = weblog.get(f"/tag_value/anything/200?content-language=krypton") @@ -621,7 +497,7 @@ def test_blocking(self): def setup_non_blocking(self): self.setup_blocking() - self.rm_req_nonblock1 = weblog.get(f"/tag_value/anything/200?content-color=en-us") + self.rm_req_nonblock1 = weblog.get(f"/tag_value/anything/200?content-color=fo-fo") self.rm_req_nonblock2 = weblog.get(f"/tag_value/anything/200?content-language=fr") def test_non_blocking(self): @@ -632,22 +508,90 @@ def test_non_blocking(self): @rfc("https://datadoghq.atlassian.net/wiki/spaces/APS/pages/2667021177/Suspicious+requests+blocking") +@scenarios.appsec_blocking @features.appsec_request_blocking class Test_Suspicious_Request_Blocking: """Test if blocking on multiple addresses with multiple rules is supported""" + def setup_blocking(self): + self.rm_req_block = weblog.get( + f"/tag_value/malicious-path-cGDgSRJvklxGOKMTNfQMViBPpKAvpFoc_malicious-uri-ypMrmzrWATkLrPKLblvpRGGltBSgHWrK/200?attack=malicious-query-SAGihOkuSwXXFDXNqAWJzNuZEdKNunrJ", + cookies={"foo": "malicious-cookie-PwXuEQEdeAjzWpCDqAzPqiUAdXJMHwtS"}, + headers={"content-type": "text/plain", "client": "malicious-header-kCgvxrYeiwUSYkAuniuGktdvzXYEPSff"}, + ) + + @irrelevant( + context.library == "ruby" and context.weblog_variant == "rack", + reason="Rack don't send anything to the server.request.path_params WAF address", + ) def test_blocking(self): """Test if requests that should be blocked are blocked""" - assert False, "TODO" + assert self.rm_req_block.status_code == 403, self.rm_req_block.request.url + interfaces.library.assert_waf_attack(self.rm_req_block, rule="tst-037-012") - def test_non_blocking(self): - """Test if requests that should not be blocked are not blocked""" - self.test_blocking() - assert False, "TODO" + def setup_blocking_before(self): + self.set_req1 = weblog.post( + "/tag_value/clean_value_3882/200?attack=malicious-query-SAGihOkuSwXXFDXNqAWJzNuZEdKNunrJ", + data={"good": "value"}, + cookies={"foo": "malicious-cookie-PwXuEQEdeAjzWpCDqAzPqiUAdXJMHwtS"}, + ) + self.block_req2 = weblog.get( + f"/tag_value/malicious-path-cGDgSRJvklxGOKMTNfQMViBPpKAvpFoc_malicious-uri-ypMrmzrWATkLrPKLblvpRGGltBSgHWrK/200?attack=malicious-query-SAGihOkuSwXXFDXNqAWJzNuZEdKNunrJ", + cookies={"foo": "malicious-cookie-PwXuEQEdeAjzWpCDqAzPqiUAdXJMHwtS"}, + headers={"content-type": "text/plain", "client": "malicious-header-kCgvxrYeiwUSYkAuniuGktdvzXYEPSff"}, + ) + @irrelevant( + context.library == "ruby" and context.weblog_variant == "rack", + reason="Rack don't send anything to the server.request.path_params WAF address", + ) def test_blocking_before(self): """Test that blocked requests are blocked before being processed""" - assert False, "TODO" + # first request should not block and must set the tag in span accordingly + assert self.set_req1.status_code == 200 + assert self.set_req1.text == "Value tagged" + interfaces.library.validate_spans(self.set_req1, _assert_custom_event_tag_presence("clean_value_3882")) + + """Test that blocked requests are blocked before being processed""" + assert self.block_req2.status_code == 403 + interfaces.library.assert_waf_attack(self.block_req2, rule="tst-037-012") + interfaces.library.validate_spans(self.block_req2, _assert_custom_event_tag_absence()) + + def setup_blocking_without_path_params(self): + self.rm_req_block = weblog.get( + f"/tag_value/path_param_malicious-uri-wX1GdUiWdVdoklf0pYBi5kQApO9i77tN/200?attack=malicious-query-T3d1nKdkTWIG03q03ix9c9UlhbGigvwQ", + cookies={"foo": "malicious-cookie-qU4sV2r6ac2nfETV7aJP9Fdt1NaWC9wB"}, + headers={"content-type": "text/plain", "client": "malicious-header-siDzyETAdkvKahD3PxlvIqcE0fMIVywE"}, + ) + + def test_blocking_without_path_params(self): + """Test if requests that should be blocked are blocked""" + assert self.rm_req_block.status_code == 403, self.rm_req_block.request.url + interfaces.library.assert_waf_attack(self.rm_req_block, rule="tst-037-013") + + def setup_blocking_before_without_path_params(self): + self.set_req1 = weblog.post( + "/tag_value/clean_value_3882/200?attack=malicious-query-T3d1nKdkTWIG03q03ix9c9UlhbGigvwQ", + data={"good": "value"}, + cookies={"foo": "malicious-cookie-qU4sV2r6ac2nfETV7aJP9Fdt1NaWC9wB"}, + ) + self.block_req2 = weblog.get( + f"/tag_value/path_param_malicious-uri-wX1GdUiWdVdoklf0pYBi5kQApO9i77tN/200?attack=malicious-query-T3d1nKdkTWIG03q03ix9c9UlhbGigvwQ", + cookies={"foo": "malicious-cookie-qU4sV2r6ac2nfETV7aJP9Fdt1NaWC9wB"}, + headers={"content-type": "text/plain", "client": "malicious-header-siDzyETAdkvKahD3PxlvIqcE0fMIVywE"}, + ) + + def test_blocking_before_without_path_params(self): + """Test that blocked requests are blocked before being processed""" + # first request should not block and must set the tag in span accordingly + assert self.set_req1.status_code == 200 + assert self.set_req1.text == "Value tagged" + interfaces.library.validate_spans(self.set_req1, _assert_custom_event_tag_presence("clean_value_3882")) + + """Test that blocked requests are blocked before being processed""" + assert self.block_req2.status_code == 403 + interfaces.library.assert_waf_attack(self.block_req2, rule="tst-037-013") + interfaces.library.validate_spans(self.block_req2, _assert_custom_event_tag_absence()) @scenarios.graphql_appsec @@ -656,7 +600,7 @@ class Test_BlockingGraphqlResolvers: """Test if blocking is supported on graphql.server.all_resolvers address""" def setup_request_block_attack(self): - """ Currently only monitoring is implemented""" + """Currently only monitoring is implemented""" self.r_attack = weblog.post( "/graphql", @@ -671,7 +615,10 @@ def setup_request_block_attack(self): ) def test_request_block_attack(self): - assert self.r_attack.status_code == 403 + assert self.r_attack.status_code == ( + # We don't change the status code in Ruby + 200 if context.library == "ruby" else 403 + ) for _, span in interfaces.library.get_root_spans(request=self.r_attack): meta = span.get("meta", {}) meta_struct = span.get("meta_struct", {}) @@ -684,9 +631,7 @@ def test_request_block_attack(self): parameters["address"] == "graphql.server.all_resolvers" or parameters["address"] == "graphql.server.resolver" ) - assert rule_triggered["rule"]["id"] == ( - "block-resolvers" if parameters["address"] == "graphql.server.resolver" else "block-all-resolvers" - ) + assert rule_triggered["rule"]["id"] == "block-resolvers" assert parameters["key_path"] == ( ["userByName", "name"] if parameters["address"] == "graphql.server.resolver" @@ -695,7 +640,7 @@ def test_request_block_attack(self): assert parameters["value"] == "testblockresolver" def setup_request_block_attack_directive(self): - """ Currently only monitoring is implemented""" + """Currently only monitoring is implemented""" self.r_attack = weblog.post( "/graphql", @@ -710,7 +655,11 @@ def setup_request_block_attack_directive(self): ) def test_request_block_attack_directive(self): - assert self.r_attack.status_code == 403 + # We don't change the status code + assert self.r_attack.status_code == ( + # We don't change the status code in Ruby + 200 if context.library == "ruby" else 403 + ) for _, span in interfaces.library.get_root_spans(request=self.r_attack): meta = span.get("meta", {}) meta_struct = span.get("meta_struct", {}) diff --git a/tests/appsec/test_client_ip.py b/tests/appsec/test_client_ip.py index 1f6fbb4e45f..e1ad88e8428 100644 --- a/tests/appsec/test_client_ip.py +++ b/tests/appsec/test_client_ip.py @@ -5,7 +5,7 @@ from utils import weblog, interfaces, scenarios, features -@scenarios.appsec_disabled +@scenarios.everything_disabled @features.appsec_standard_tags_client_ip class Test_StandardTagsClientIp: """Tests to verify that libraries annotate spans with correct http.client_ip tags""" diff --git a/tests/appsec/test_conf.py b/tests/appsec/test_conf.py index debc5cd0420..00d7a1636eb 100644 --- a/tests/appsec/test_conf.py +++ b/tests/appsec/test_conf.py @@ -10,65 +10,10 @@ TELEMETRY_REQUEST_TYPE_GENERATE_METRICS = "generate-metrics" -@features.threats_configuration -class Test_StaticRuleSet: - """Appsec loads rules from a static rules file""" - - @missing_feature(library="golang", reason="standard logs not implemented") - @missing_feature(library="ruby", reason="standard logs not implemented") - @missing_feature(library="php", reason="Rules file is not parsed") - @missing_feature(library="nodejs", reason="Rules file is not parsed") - def test_basic_hardcoded_ruleset(self): - """ Library has loaded a hardcoded AppSec ruleset""" - stdout = interfaces.library_stdout if context.library != "dotnet" else interfaces.library_dotnet_managed - stdout.assert_presence(r"AppSec loaded \d+ rules from file ?$", level="INFO") - - -@features.threats_configuration -class Test_RuleSet_1_2_4: - """ AppSec uses rule set 1.2.4 or higher """ - - def test_main(self): - assert context.appsec_rules_version >= "1.2.4" - - -@features.threats_configuration -class Test_RuleSet_1_2_5: - """ AppSec uses rule set 1.2.5 or higher """ - - def test_main(self): - assert context.appsec_rules_version >= "1.2.5" - - -@features.threats_configuration -class Test_RuleSet_1_3_1: - """ AppSec uses rule set 1.3.1 or higher """ - - def test_main(self): - """ Test rule set version number""" - assert context.appsec_rules_version >= "1.3.1" - - def setup_nosqli_keys(self): - self.r_keys = weblog.get("/waf/", params={"$nin": "value"}) - - def test_nosqli_keys(self): - """Test a rule defined on this rules version: nosql on keys""" - interfaces.library.assert_waf_attack(self.r_keys, waf_rules.nosql_injection) - - def setup_nosqli_keys_with_brackets(self): - self.r_keys2 = weblog.get("/waf/", params={"[$ne]": "value"}) - - @irrelevant(library="php", reason="The PHP runtime interprets brackets as arrays, so this is considered malformed") - @irrelevant(library="nodejs", reason="Node interprets brackets as arrays, so they're truncated") - def test_nosqli_keys_with_brackets(self): - """Test a rule defined on this rules version: nosql on keys with brackets""" - interfaces.library.assert_waf_attack(self.r_keys2, waf_rules.nosql_injection.crs_942_290) - - @rfc("https://datadoghq.atlassian.net/wiki/spaces/APS/pages/2355333252/Environment+Variables") @features.threats_configuration class Test_ConfigurationVariables: - """ Configuration environment variables """ + """Configuration environment variables""" SECRET = "This-value-is-secret" @@ -79,20 +24,16 @@ def setup_enabled(self): self.r_enabled = weblog.get("/waf/", headers={"User-Agent": "Arachni/v1"}) def test_enabled(self): - """ test DD_APPSEC_ENABLED = true """ + """test DD_APPSEC_ENABLED = true""" interfaces.library.assert_waf_attack(self.r_enabled) def setup_disabled(self): self.r_disabled = weblog.get("/waf/", headers={"User-Agent": "Arachni/v1"}) @irrelevant(library="ruby", weblog_variant="rack", reason="it's not possible to auto instrument with rack") - @missing_feature( - context.weblog_variant in ["sinatra14", "sinatra20", "sinatra21", "uds-sinatra"], - reason="Conf is done in weblog instead of library", - ) - @scenarios.appsec_disabled + @scenarios.everything_disabled def test_disabled(self): - """ test DD_APPSEC_ENABLED = false """ + """test DD_APPSEC_ENABLED = false""" interfaces.library.assert_no_appsec_event(self.r_disabled) def setup_appsec_rules(self): @@ -100,7 +41,7 @@ def setup_appsec_rules(self): @scenarios.appsec_custom_rules def test_appsec_rules(self): - """ test DD_APPSEC_RULES = custom rules file """ + """test DD_APPSEC_RULES = custom rules file""" interfaces.library.assert_waf_attack(self.r_appsec_rules, pattern="dedicated-value-for-testing-purpose") def setup_waf_timeout(self): @@ -114,7 +55,7 @@ def setup_waf_timeout(self): @missing_feature(context.library == "java" and context.weblog_variant == "spring-boot-wildfly") @scenarios.appsec_low_waf_timeout def test_waf_timeout(self): - """ test DD_APPSEC_WAF_TIMEOUT = low value """ + """test DD_APPSEC_WAF_TIMEOUT = low value""" interfaces.library.assert_no_appsec_event(self.r_waf_timeout) def setup_obfuscation_parameter_key(self): @@ -124,7 +65,7 @@ def setup_obfuscation_parameter_key(self): @missing_feature(context.library < f"python@{PYTHON_RELEASE_GA_1_1}") @scenarios.appsec_custom_obfuscation def test_obfuscation_parameter_key(self): - """ test DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP """ + """test DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP""" def validate_appsec_span_tags(span, appsec_data): # pylint: disable=unused-argument assert not nested_lookup( @@ -142,7 +83,7 @@ def setup_obfuscation_parameter_value(self): @missing_feature(context.library < f"python@{PYTHON_RELEASE_GA_1_1}") @scenarios.appsec_custom_obfuscation def test_obfuscation_parameter_value(self): - """ test DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP """ + """test DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP""" def validate_appsec_span_tags(span, appsec_data): # pylint: disable=unused-argument assert not nested_lookup( diff --git a/tests/appsec/test_customconf.py b/tests/appsec/test_customconf.py index d893bfbfa92..d9c5278543d 100644 --- a/tests/appsec/test_customconf.py +++ b/tests/appsec/test_customconf.py @@ -2,7 +2,7 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -from utils import weblog, context, interfaces, bug, missing_feature, scenarios, features +from utils import weblog, context, interfaces, bug, scenarios, features # get the default log output @@ -18,19 +18,11 @@ def setup_c05(self): self.r_1 = weblog.get("/", headers={"User-Agent": "Arachni/v1"}) self.r_2 = weblog.get("/waf", params={"attack": " - - -
- - -
- - - - -
-

Getting started

-

Here’s how to get rolling:

- -
    -
  1. -

    Use rails generate to create your models and controllers

    -

    To see all available options, run it without parameters.

    -
  2. - -
  3. -

    Set up a default route and remove public/index.html

    -

    Routes are set up in config/routes.rb.

    -
  4. - -
  5. -

    Create your database

    -

    Run rake db:create to create your database. If you're not using SQLite (the default), edit config/database.yml with your username and password.

    -
  6. -
-
-
- - -
- - diff --git a/utils/build/docker/ruby/rails32/public/robots.txt b/utils/build/docker/ruby/rails32/public/robots.txt deleted file mode 100644 index 085187fa58b..00000000000 --- a/utils/build/docker/ruby/rails32/public/robots.txt +++ /dev/null @@ -1,5 +0,0 @@ -# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file -# -# To ban all spiders from the entire site uncomment the next two lines: -# User-Agent: * -# Disallow: / diff --git a/utils/build/docker/ruby/rails32/script/rails b/utils/build/docker/ruby/rails32/script/rails deleted file mode 100755 index f8da2cffd4d..00000000000 --- a/utils/build/docker/ruby/rails32/script/rails +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env ruby -# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. - -APP_PATH = File.expand_path('../../config/application', __FILE__) -require File.expand_path('../../config/boot', __FILE__) -require 'rails/commands' diff --git a/utils/build/docker/ruby/rails32/test/performance/browsing_test.rb b/utils/build/docker/ruby/rails32/test/performance/browsing_test.rb deleted file mode 100644 index 3fea27b9167..00000000000 --- a/utils/build/docker/ruby/rails32/test/performance/browsing_test.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'test_helper' -require 'rails/performance_test_help' - -class BrowsingTest < ActionDispatch::PerformanceTest - # Refer to the documentation for all available options - # self.profile_options = { :runs => 5, :metrics => [:wall_time, :memory] - # :output => 'tmp/performance', :formats => [:flat] } - - def test_homepage - get '/' - end -end diff --git a/utils/build/docker/ruby/rails32/test/test_helper.rb b/utils/build/docker/ruby/rails32/test/test_helper.rb deleted file mode 100644 index 8bf1192ffec..00000000000 --- a/utils/build/docker/ruby/rails32/test/test_helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -ENV["RAILS_ENV"] = "test" -require File.expand_path('../../config/environment', __FILE__) -require 'rails/test_help' - -class ActiveSupport::TestCase - # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. - # - # Note: You'll currently still have to declare fixtures explicitly in integration tests - # -- they do not yet inherit this setting - fixtures :all - - # Add more helper methods to be used by all tests here... -end diff --git a/utils/build/docker/ruby/rails40.Dockerfile b/utils/build/docker/ruby/rails40.Dockerfile deleted file mode 100644 index ff7ade069ab..00000000000 --- a/utils/build/docker/ruby/rails40.Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:2.3.8-dd - -RUN curl -O https://rubygems.org/downloads/libv8-node-15.14.0.1-$(arch)-linux.gem && gem install libv8-node-15.14.0.1-$(arch)-linux.gem && rm libv8-node-15.14.0.1-$(arch)-linux.gem - -RUN mkdir -p /app -WORKDIR /app - -COPY utils/build/docker/ruby/rails40/ . - -COPY utils/build/docker/ruby/install_ddtrace.sh binaries* /binaries/ -RUN /binaries/install_ddtrace.sh - -ENV DD_TRACE_HEADER_TAGS=user-agent -ENV RAILS_ENV=production -RUN bundle exec rake db:create db:migrate db:seed - -RUN echo "#!/bin/bash\nbundle exec thin start -p 7777" > app.sh -RUN chmod +x app.sh -CMD [ "./app.sh" ] diff --git a/utils/build/docker/ruby/rails40/.dockerignore b/utils/build/docker/ruby/rails40/.dockerignore deleted file mode 100644 index 209439b011e..00000000000 --- a/utils/build/docker/ruby/rails40/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -.envrc -shell.nix -vendor/bundle diff --git a/utils/build/docker/ruby/rails40/.gitignore b/utils/build/docker/ruby/rails40/.gitignore deleted file mode 100644 index 6a502e997fe..00000000000 --- a/utils/build/docker/ruby/rails40/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -# See https://help.github.com/articles/ignoring-files for more about ignoring files. -# -# If you find yourself ignoring temporary files generated by your text editor -# or operating system, you probably want to add a global ignore instead: -# git config --global core.excludesfile '~/.gitignore_global' - -# Ignore bundler config. -/.bundle - -# Ignore the default SQLite database. -/db/*.sqlite3 -/db/*.sqlite3-journal - -# Ignore all logfiles and tempfiles. -/log/*.log -/tmp diff --git a/utils/build/docker/ruby/rails40/Gemfile b/utils/build/docker/ruby/rails40/Gemfile deleted file mode 100644 index 1e22ebb1d74..00000000000 --- a/utils/build/docker/ruby/rails40/Gemfile +++ /dev/null @@ -1,52 +0,0 @@ -source 'http://rubygems.org' - -# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '4.0.13' - -# Use sqlite3 as the database for Active Record -gem 'sqlite3', '< 1.4' - -# Use SCSS for stylesheets -gem 'sass-rails', '~> 4.0.2' - -# Use Uglifier as compressor for JavaScript assets -gem 'uglifier', '>= 1.3.0' - -# Use CoffeeScript for .js.coffee assets and views -gem 'coffee-rails', '~> 4.0.0' - -# See https://github.com/sstephenson/execjs#readme for more supported runtimes -gem 'mini_racer', '~> 0.4.0', platforms: :ruby - -# Use jquery as the JavaScript library -gem 'jquery-rails' - -# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks -gem 'turbolinks' - -# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder -gem 'jbuilder', '~> 1.2' - -group :doc do - # bundle exec rake doc:rails generates the API under doc/api. - gem 'sdoc', require: false -end - -# Use ActiveModel has_secure_password -# gem 'bcrypt', '~> 3.1.7' - -# Use unicorn as the app server -# gem 'unicorn' - -# Use Capistrano for deployment -# gem 'capistrano', group: :development - -# Use debugger -# gem 'debugger', group: [:development, :test] - -gem 'pry' -gem 'devise' -gem 'ddtrace', '~> 1.0.0.a', require: 'ddtrace/auto_instrument' -gem 'ffi', '~> 1.12.2' # Ruby < 2.3 -gem 'msgpack', '~> 1.3.3' # Ruby < 2.4 -gem 'thin' diff --git a/utils/build/docker/ruby/rails40/Gemfile.lock b/utils/build/docker/ruby/rails40/Gemfile.lock deleted file mode 100644 index 29e8f5fb8b7..00000000000 --- a/utils/build/docker/ruby/rails40/Gemfile.lock +++ /dev/null @@ -1,170 +0,0 @@ -GEM - remote: http://rubygems.org/ - specs: - actionmailer (4.0.13) - actionpack (= 4.0.13) - mail (~> 2.5, >= 2.5.4) - actionpack (4.0.13) - activesupport (= 4.0.13) - builder (~> 3.1.0) - erubis (~> 2.7.0) - rack (~> 1.5.2) - rack-test (~> 0.6.2) - activemodel (4.0.13) - activesupport (= 4.0.13) - builder (~> 3.1.0) - activerecord (4.0.13) - activemodel (= 4.0.13) - activerecord-deprecated_finders (~> 1.0.2) - activesupport (= 4.0.13) - arel (~> 4.0.0) - activerecord-deprecated_finders (1.0.4) - activesupport (4.0.13) - i18n (~> 0.6, >= 0.6.9) - minitest (~> 4.2) - multi_json (~> 1.3) - thread_safe (~> 0.1) - tzinfo (~> 0.3.37) - arel (4.0.2) - bcrypt (3.1.20) - builder (3.1.4) - coderay (1.1.3) - coffee-rails (4.0.1) - coffee-script (>= 2.2.0) - railties (>= 4.0.0, < 5.0) - coffee-script (2.4.1) - coffee-script-source - execjs - coffee-script-source (1.12.2) - concurrent-ruby (1.1.9) - daemons (1.4.1) - ddtrace (1.0.0.beta1) - debase-ruby_core_source (<= 0.10.14) - libddwaf (~> 1.0.14.2.0.a) - msgpack - debase-ruby_core_source (0.10.14) - devise (3.5.10) - bcrypt (~> 3.0) - orm_adapter (~> 0.1) - railties (>= 3.2.6, < 5) - responders - thread_safe (~> 0.1) - warden (~> 1.2.3) - erubis (2.7.0) - eventmachine (1.2.7) - execjs (2.8.1) - ffi (1.12.2) - hike (1.2.3) - i18n (0.9.5) - concurrent-ruby (~> 1.0) - jbuilder (1.5.3) - activesupport (>= 3.0.0) - multi_json (>= 1.2.0) - jquery-rails (3.1.5) - railties (>= 3.0, < 5.0) - thor (>= 0.14, < 2.0) - libddwaf (1.0.14.2.0.beta1) - ffi (~> 1.0) - libddwaf (1.0.14.2.0.beta1-aarch64-linux) - ffi (~> 1.0) - libddwaf (1.0.14.2.0.beta1-arm64-darwin) - ffi (~> 1.0) - libddwaf (1.0.14.2.0.beta1-x86_64-darwin) - ffi (~> 1.0) - libddwaf (1.0.14.2.0.beta1-x86_64-linux) - ffi (~> 1.0) - libv8-node (15.14.0.1) - mail (2.7.1) - mini_mime (>= 0.1.1) - method_source (1.0.0) - mini_mime (1.1.2) - mini_racer (0.4.0) - libv8-node (~> 15.14.0.0) - minitest (4.7.5) - msgpack (1.3.3) - multi_json (1.15.0) - orm_adapter (0.5.0) - pry (0.14.1) - coderay (~> 1.1) - method_source (~> 1.0) - rack (1.5.5) - rack-test (0.6.3) - rack (>= 1.0) - rails (4.0.13) - actionmailer (= 4.0.13) - actionpack (= 4.0.13) - activerecord (= 4.0.13) - activesupport (= 4.0.13) - bundler (>= 1.3.0, < 2.0) - railties (= 4.0.13) - sprockets-rails (~> 2.0) - railties (4.0.13) - actionpack (= 4.0.13) - activesupport (= 4.0.13) - rake (>= 0.8.7) - thor (>= 0.18.1, < 2.0) - rake (13.0.6) - rdoc (6.2.0) - responders (1.1.2) - railties (>= 3.2, < 4.2) - sass (3.2.19) - sass-rails (4.0.5) - railties (>= 4.0.0, < 5.0) - sass (~> 3.2.2) - sprockets (~> 2.8, < 3.0) - sprockets-rails (~> 2.0) - sdoc (2.3.0) - rdoc (>= 5.0, < 6.4.0) - sprockets (2.12.5) - hike (~> 1.2) - multi_json (~> 1.0) - rack (~> 1.0) - tilt (~> 1.1, != 1.3.0) - sprockets-rails (2.3.3) - actionpack (>= 3.0) - activesupport (>= 3.0) - sprockets (>= 2.8, < 4.0) - sqlite3 (1.3.13) - thin (1.8.1) - daemons (~> 1.0, >= 1.0.9) - eventmachine (~> 1.0, >= 1.0.4) - rack (>= 1, < 3) - thor (1.2.1) - thread_safe (0.3.6) - tilt (1.4.1) - turbolinks (5.2.1) - turbolinks-source (~> 5.2) - turbolinks-source (5.2.0) - tzinfo (0.3.60) - uglifier (4.2.0) - execjs (>= 0.3.0, < 3) - warden (1.2.7) - rack (>= 1.0) - -PLATFORMS - aarch64-linux - arm64-darwin - ruby - x86_64-darwin - x86_64-linux - -DEPENDENCIES - coffee-rails (~> 4.0.0) - ddtrace (~> 1.0.0.a) - devise - ffi (~> 1.12.2) - jbuilder (~> 1.2) - jquery-rails - mini_racer (~> 0.4.0) - msgpack (~> 1.3.3) - pry - rails (= 4.0.13) - sass-rails (~> 4.0.2) - sdoc - sqlite3 (< 1.4) - thin - turbolinks - uglifier (>= 1.3.0) - -BUNDLED WITH - 1.17.3 diff --git a/utils/build/docker/ruby/rails40/README.rdoc b/utils/build/docker/ruby/rails40/README.rdoc deleted file mode 100644 index dd4e97e22e1..00000000000 --- a/utils/build/docker/ruby/rails40/README.rdoc +++ /dev/null @@ -1,28 +0,0 @@ -== README - -This README would normally document whatever steps are necessary to get the -application up and running. - -Things you may want to cover: - -* Ruby version - -* System dependencies - -* Configuration - -* Database creation - -* Database initialization - -* How to run the test suite - -* Services (job queues, cache servers, search engines, etc.) - -* Deployment instructions - -* ... - - -Please feel free to use a different markup language if you do not plan to run -rake doc:app. diff --git a/utils/build/docker/ruby/rails40/Rakefile b/utils/build/docker/ruby/rails40/Rakefile deleted file mode 100644 index e378bc7fee0..00000000000 --- a/utils/build/docker/ruby/rails40/Rakefile +++ /dev/null @@ -1,6 +0,0 @@ -# Add your own tasks in files placed in lib/tasks ending in .rake, -# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. - -require File.expand_path('../config/application', __FILE__) - -Rails40::Application.load_tasks diff --git a/utils/build/docker/ruby/rails40/app/assets/javascripts/application.js b/utils/build/docker/ruby/rails40/app/assets/javascripts/application.js deleted file mode 100644 index d6925fa431b..00000000000 --- a/utils/build/docker/ruby/rails40/app/assets/javascripts/application.js +++ /dev/null @@ -1,16 +0,0 @@ -// This is a manifest file that'll be compiled into application.js, which will include all the files -// listed below. -// -// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, -// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. -// -// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the -// compiled file. -// -// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details -// about supported directives. -// -//= require jquery -//= require jquery_ujs -//= require turbolinks -//= require_tree . diff --git a/utils/build/docker/ruby/rails40/app/assets/stylesheets/application.css b/utils/build/docker/ruby/rails40/app/assets/stylesheets/application.css deleted file mode 100644 index 3192ec897bb..00000000000 --- a/utils/build/docker/ruby/rails40/app/assets/stylesheets/application.css +++ /dev/null @@ -1,13 +0,0 @@ -/* - * This is a manifest file that'll be compiled into application.css, which will include all the files - * listed below. - * - * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, - * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. - * - * You're free to add application-wide styles to this file and they'll appear at the top of the - * compiled file, but it's generally better to create a new file per style scope. - * - *= require_self - *= require_tree . - */ diff --git a/utils/build/docker/ruby/rails40/app/controllers/application_controller.rb b/utils/build/docker/ruby/rails40/app/controllers/application_controller.rb deleted file mode 100644 index d83690e1b9a..00000000000 --- a/utils/build/docker/ruby/rails40/app/controllers/application_controller.rb +++ /dev/null @@ -1,5 +0,0 @@ -class ApplicationController < ActionController::Base - # Prevent CSRF attacks by raising an exception. - # For APIs, you may want to use :null_session instead. - protect_from_forgery with: :exception -end diff --git a/utils/build/docker/ruby/rails40/app/controllers/system_test_controller.rb b/utils/build/docker/ruby/rails40/app/controllers/system_test_controller.rb deleted file mode 100644 index bae45abfbbb..00000000000 --- a/utils/build/docker/ruby/rails40/app/controllers/system_test_controller.rb +++ /dev/null @@ -1,145 +0,0 @@ -require 'datadog/kit/appsec/events' - -class SystemTestController < ApplicationController - skip_before_action :verify_authenticity_token - - def root - render text: 'Hello, world!' - end - - def waf - render text: 'Hello, world!' - end - - def handle_path_params - render text: 'Hello, world!' - end - - def status - render text: "Ok", status: params[:code] - end - - def generate_spans - begin - repeats = Integer(request.params['repeats'] || 0) - garbage = Integer(request.params['garbage'] || 0) - rescue ArgumentError - render text: 'bad request', status: 400 - else - repeats.times do |i| - Datadog::Tracing.trace('repeat-#{i}') do |span| - garbage.times do |j| - span.set_tag("garbage-#{j}", "#{j}") - end - end - end - end - - render text: 'Generated #{repeats} spans with #{garbage} garbage tags' - end - - def test_headers - response.headers['Content-Type'] ='text/plain' - response.headers['Content-Length'] ='15' - response.headers['Content-Language'] ='en-US' - - render text: 'Hello, headers!' - end - - def identify - trace = Datadog::Tracing.active_trace - trace.set_tag('usr.id', 'usr.id') - trace.set_tag('usr.name', 'usr.name') - trace.set_tag('usr.email', 'usr.email') - trace.set_tag('usr.session_id', 'usr.session_id') - trace.set_tag('usr.role', 'usr.role') - trace.set_tag('usr.scope', 'usr.scope') - - render text: 'Hello, world!' - end - - def user_login_success_event - Datadog::Kit::AppSec::Events.track_login_success( - Datadog::Tracing.active_trace, user: {id: 'system_tests_user'}, metadata0: "value0", metadata1: "value1" - ) - - render text: 'Hello, world!' - end - - def user_login_failure_event - Datadog::Kit::AppSec::Events.track_login_failure( - Datadog::Tracing.active_trace, user_id: 'system_tests_user', user_exists: true, metadata0: "value0", metadata1: "value1" - ) - - render text: 'Hello, world!' - end - - def custom_event - Datadog::Kit::AppSec::Events.track('system_tests_event', Datadog::Tracing.active_trace, metadata0: "value0", metadata1: "value1") - - render text: 'Hello, world!' - end - - def tag_value - event_value = params[:tag_value] - status_code = params[:status_code] - - if request.method == "POST" && event_value.include?('payload_in_response_body') - render json: { payload: request.POST } - return - end - - headers = request.query_string.split('&').map {|e | e.split('=')} || [] - - trace = Datadog::Tracing.active_trace - trace.set_tag("appsec.events.system_tests_appsec_event.value", event_value) - - headers.each do |key, value| - response.headers[key] = value - end - - render text: 'Value tagged', status: status_code - end - - def users - user_id = request.params["user"] - - Datadog::Kit::Identity.set_user(id: user_id) - - render text: 'Hello, user!' - end - - def login - request.env["devise.allow_params_authentication"] = true - - sdk_event = request.params[:sdk_event] - sdk_user = request.params[:sdk_user] - sdk_email = request.params[:sdk_mail] - sdk_exists = request.params[:sdk_user_exists] - - if sdk_exists - sdk_exists = sdk_exists == "true" - end - - result = request.env['warden'].authenticate({ scope: Devise.mappings[:user].name }) - - if sdk_event === 'failure' && sdk_user - metadata = {} - metadata[:email] = sdk_email if sdk_email - Datadog::Kit::AppSec::Events.track_login_failure(user_id: sdk_user, user_exists: sdk_exists, **metadata) - elsif sdk_event === 'success' && sdk_user - user = {} - user[:id] = sdk_user - user[:email] = sdk_email if sdk_email - Datadog::Kit::AppSec::Events.track_login_success(user: user) - end - - unless result - render text: '', status: 401 - return - end - - - render text: 'Hello, world!' - end -end diff --git a/utils/build/docker/ruby/rails40/app/models/user.rb b/utils/build/docker/ruby/rails40/app/models/user.rb deleted file mode 100644 index 634e20d9a7a..00000000000 --- a/utils/build/docker/ruby/rails40/app/models/user.rb +++ /dev/null @@ -1,6 +0,0 @@ -class User < ActiveRecord::Base - # Include default devise modules. Others available are: - # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable - devise :database_authenticatable, :registerable, - :recoverable, :rememberable, :validatable -end diff --git a/utils/build/docker/ruby/rails40/app/views/layouts/application.html.erb b/utils/build/docker/ruby/rails40/app/views/layouts/application.html.erb deleted file mode 100644 index 65bb5ddb964..00000000000 --- a/utils/build/docker/ruby/rails40/app/views/layouts/application.html.erb +++ /dev/null @@ -1,14 +0,0 @@ - - - - Rails40 - <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> - <%= javascript_include_tag "application", "data-turbolinks-track" => true %> - <%= csrf_meta_tags %> - - - -<%= yield %> - - - diff --git a/utils/build/docker/ruby/rails40/config.ru b/utils/build/docker/ruby/rails40/config.ru deleted file mode 100644 index 5bc2a619e83..00000000000 --- a/utils/build/docker/ruby/rails40/config.ru +++ /dev/null @@ -1,4 +0,0 @@ -# This file is used by Rack-based servers to start the application. - -require ::File.expand_path('../config/environment', __FILE__) -run Rails.application diff --git a/utils/build/docker/ruby/rails40/config/application.rb b/utils/build/docker/ruby/rails40/config/application.rb deleted file mode 100644 index f83a2ab98be..00000000000 --- a/utils/build/docker/ruby/rails40/config/application.rb +++ /dev/null @@ -1,27 +0,0 @@ -require File.expand_path('../boot', __FILE__) - -require 'rails/all' - -# Require the gems listed in Gemfile, including any gems -# you've limited to :test, :development, or :production. -Bundler.require(*Rails.groups) - -module Rails40 - class Application < Rails::Application - # Settings in config/environments/* take precedence over those specified here. - # Application configuration should go into files in config/initializers - # -- all .rb files in that directory are automatically loaded. - - # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. - # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. - # config.time_zone = 'Central Time (US & Canada)' - - # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. - # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] - # config.i18n.default_locale = :de - - # With Rails 4 there is an issue with the Rack::Lock middleware - # For more information check https://github.com/rails/rails/issues/20660 - config.middleware.delete Rack::Lock - end -end diff --git a/utils/build/docker/ruby/rails40/config/boot.rb b/utils/build/docker/ruby/rails40/config/boot.rb deleted file mode 100644 index 5e5f0c1fac0..00000000000 --- a/utils/build/docker/ruby/rails40/config/boot.rb +++ /dev/null @@ -1,4 +0,0 @@ -# Set up gems listed in the Gemfile. -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) - -require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) diff --git a/utils/build/docker/ruby/rails40/config/database.yml b/utils/build/docker/ruby/rails40/config/database.yml deleted file mode 100644 index 51a4dd459dc..00000000000 --- a/utils/build/docker/ruby/rails40/config/database.yml +++ /dev/null @@ -1,25 +0,0 @@ -# SQLite version 3.x -# gem install sqlite3 -# -# Ensure the SQLite 3 gem is defined in your Gemfile -# gem 'sqlite3' -development: - adapter: sqlite3 - database: db/development.sqlite3 - pool: 5 - timeout: 5000 - -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. -test: - adapter: sqlite3 - database: db/test.sqlite3 - pool: 5 - timeout: 5000 - -production: - adapter: sqlite3 - database: db/production.sqlite3 - pool: 5 - timeout: 5000 diff --git a/utils/build/docker/ruby/rails40/config/environment.rb b/utils/build/docker/ruby/rails40/config/environment.rb deleted file mode 100644 index b2cb1248da3..00000000000 --- a/utils/build/docker/ruby/rails40/config/environment.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Load the Rails application. -require File.expand_path('../application', __FILE__) - -# Initialize the Rails application. -Rails40::Application.initialize! diff --git a/utils/build/docker/ruby/rails40/config/environments/development.rb b/utils/build/docker/ruby/rails40/config/environments/development.rb deleted file mode 100644 index 5100cbc6f42..00000000000 --- a/utils/build/docker/ruby/rails40/config/environments/development.rb +++ /dev/null @@ -1,32 +0,0 @@ -Rails40::Application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # In the development environment your application's code is reloaded on - # every request. This slows down response time but is perfect for development - # since you don't have to restart the web server when you make code changes. - config.cache_classes = false - - # Do not eager load code on boot. - config.eager_load = false - - # Show full error reports and disable caching. - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - - # Don't care if the mailer can't send. - config.action_mailer.raise_delivery_errors = false - - # Print deprecation notices to the Rails logger. - config.active_support.deprecation = :log - - # Raise an error on page load if there are pending migrations - config.active_record.migration_error = :page_load - - # Debug mode disables concatenation and preprocessing of assets. - # This option may cause significant delays in view rendering with a large - # number of complex assets. - config.assets.debug = true - - # Raises error for missing translations - # config.action_view.raise_on_missing_translations = true -end diff --git a/utils/build/docker/ruby/rails40/config/environments/production.rb b/utils/build/docker/ruby/rails40/config/environments/production.rb deleted file mode 100644 index 8a3e8514d82..00000000000 --- a/utils/build/docker/ruby/rails40/config/environments/production.rb +++ /dev/null @@ -1,80 +0,0 @@ -Rails40::Application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # Code is not reloaded between requests. - config.cache_classes = true - - # Eager load code on boot. This eager loads most of Rails and - # your application in memory, allowing both thread web servers - # and those relying on copy on write to perform better. - # Rake tasks automatically ignore this option for performance. - config.eager_load = true - - # Full error reports are disabled and caching is turned on. - config.consider_all_requests_local = false - config.action_controller.perform_caching = true - - # Enable Rack::Cache to put a simple HTTP cache in front of your application - # Add `rack-cache` to your Gemfile before enabling this. - # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid. - # config.action_dispatch.rack_cache = true - - # Disable Rails's static asset server (Apache or nginx will already do this). - config.serve_static_assets = false - - # Compress JavaScripts and CSS. - config.assets.js_compressor = :uglifier - # config.assets.css_compressor = :sass - - # Do not fallback to assets pipeline if a precompiled asset is missed. - config.assets.compile = false - - # Generate digests for assets URLs. - config.assets.digest = true - - # Version of your assets, change this if you want to expire all your assets. - config.assets.version = '1.0' - - # Specifies the header that your server uses for sending files. - # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache - # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx - - # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - # config.force_ssl = true - - # Set to :debug to see everything in the log. - config.log_level = :info - - # Prepend all log lines with the following tags. - # config.log_tags = [ :subdomain, :uuid ] - - # Use a different logger for distributed setups. - # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) - - # Use a different cache store in production. - # config.cache_store = :mem_cache_store - - # Enable serving of images, stylesheets, and JavaScripts from an asset server. - # config.action_controller.asset_host = "http://assets.example.com" - - # Precompile additional assets. - # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. - # config.assets.precompile += %w( search.js ) - - # Ignore bad email addresses and do not raise email delivery errors. - # Set this to true and configure the email server for immediate delivery to raise delivery errors. - # config.action_mailer.raise_delivery_errors = false - - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to - # the I18n.default_locale when a translation can not be found). - config.i18n.fallbacks = true - - # Send deprecation notices to registered listeners. - config.active_support.deprecation = :notify - - # Disable automatic flushing of the log to improve performance. - # config.autoflush_log = false - - # Use default logging formatter so that PID and timestamp are not suppressed. - config.log_formatter = ::Logger::Formatter.new -end diff --git a/utils/build/docker/ruby/rails40/config/environments/test.rb b/utils/build/docker/ruby/rails40/config/environments/test.rb deleted file mode 100644 index ddca1ca372e..00000000000 --- a/utils/build/docker/ruby/rails40/config/environments/test.rb +++ /dev/null @@ -1,39 +0,0 @@ -Rails40::Application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! - config.cache_classes = true - - # Do not eager load code on boot. This avoids loading your whole application - # just for the purpose of running a single test. If you are using a tool that - # preloads Rails for running tests, you may have to set it to true. - config.eager_load = false - - # Configure static asset server for tests with Cache-Control for performance. - config.serve_static_assets = true - config.static_cache_control = "public, max-age=3600" - - # Show full error reports and disable caching. - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - - # Raise exceptions instead of rendering exception templates. - config.action_dispatch.show_exceptions = false - - # Disable request forgery protection in test environment. - config.action_controller.allow_forgery_protection = false - - # Tell Action Mailer not to deliver emails to the real world. - # The :test delivery method accumulates sent emails in the - # ActionMailer::Base.deliveries array. - config.action_mailer.delivery_method = :test - - # Print deprecation notices to the stderr. - config.active_support.deprecation = :stderr - - # Raises error for missing translations - # config.action_view.raise_on_missing_translations = true -end diff --git a/utils/build/docker/ruby/rails40/config/initializers/backtrace_silencers.rb b/utils/build/docker/ruby/rails40/config/initializers/backtrace_silencers.rb deleted file mode 100644 index 59385cdf379..00000000000 --- a/utils/build/docker/ruby/rails40/config/initializers/backtrace_silencers.rb +++ /dev/null @@ -1,7 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. -# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } - -# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. -# Rails.backtrace_cleaner.remove_silencers! diff --git a/utils/build/docker/ruby/rails40/config/initializers/devise.rb b/utils/build/docker/ruby/rails40/config/initializers/devise.rb deleted file mode 100644 index a25dd104c77..00000000000 --- a/utils/build/docker/ruby/rails40/config/initializers/devise.rb +++ /dev/null @@ -1,304 +0,0 @@ -# frozen_string_literal: true - -# Assuming you have not yet modified this file, each configuration option below -# is set to its default value. Note that some are commented out while others -# are not: uncommented lines are intended to protect your configuration from -# breaking changes in upgrades (i.e., in the event that future versions of -# Devise change the default values for those options). -# -# Use this hook to configure devise mailer, warden hooks and so forth. -# Many of these configuration options can be set straight in your model. -Devise.setup do |config| - # The secret key used by Devise. Devise uses this key to generate - # random tokens. Changing this key will render invalid all existing - # confirmation, reset password and unlock tokens in the database. - # Devise will use the `secret_key_base` as its `secret_key` - # by default. You can change it below and use your own secret key. - # config.secret_key = '2aa7763a03b8aeefb5507ab110519240bbd9c017f8c15c8e5d652871ebdc194735d7acda52f0a3eef7a46fb2f16bc4a0eeacd1542a3f63ad6d56e38a15484fa8' - - # ==> Controller configuration - # Configure the parent class to the devise controllers. - # config.parent_controller = 'DeviseController' - - # ==> Mailer Configuration - # Configure the e-mail address which will be shown in Devise::Mailer, - # note that it will be overwritten if you use your own mailer class - # with default "from" parameter. - config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' - - # Configure the class responsible to send e-mails. - # config.mailer = 'Devise::Mailer' - - # Configure the parent class responsible to send e-mails. - # config.parent_mailer = 'ActionMailer::Base' - - # ==> ORM configuration - # Load and configure the ORM. Supports :active_record (default) and - # :mongoid (bson_ext recommended) by default. Other ORMs may be - # available as additional gems. - require 'devise/orm/active_record' - - # ==> Configuration for any authentication mechanism - # Configure which keys are used when authenticating a user. The default is - # just :email. You can configure it to use [:username, :subdomain], so for - # authenticating a user, both parameters are required. Remember that those - # parameters are used only when authenticating and not when retrieving from - # session. If you need permissions, you should implement that in a before filter. - # You can also supply a hash where the value is a boolean determining whether - # or not authentication should be aborted when the value is not present. - config.authentication_keys = [ :username ] - - # Configure parameters from the request object used for authentication. Each entry - # given should be a request method and it will automatically be passed to the - # find_for_authentication method and considered in your model lookup. For instance, - # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. - # The same considerations mentioned for authentication_keys also apply to request_keys. - # config.request_keys = [] - - # Configure which authentication keys should be case-insensitive. - # These keys will be downcased upon creating or modifying a user and when used - # to authenticate or find a user. Default is :email. - config.case_insensitive_keys = [:email] - - # Configure which authentication keys should have whitespace stripped. - # These keys will have whitespace before and after removed upon creating or - # modifying a user and when used to authenticate or find a user. Default is :email. - config.strip_whitespace_keys = [:email] - - # Tell if authentication through request.params is enabled. True by default. - # It can be set to an array that will enable params authentication only for the - # given strategies, for example, `config.params_authenticatable = [:database]` will - # enable it only for database (email + password) authentication. - # config.params_authenticatable = true - - # Tell if authentication through HTTP Auth is enabled. False by default. - # It can be set to an array that will enable http authentication only for the - # given strategies, for example, `config.http_authenticatable = [:database]` will - # enable it only for database authentication. - # For API-only applications to support authentication "out-of-the-box", you will likely want to - # enable this with :database unless you are using a custom strategy. - # The supported strategies are: - # :database = Support basic authentication with authentication key + password - config.http_authenticatable = true - - # If 401 status code should be returned for AJAX requests. True by default. - # config.http_authenticatable_on_xhr = true - - # The realm used in Http Basic Authentication. 'Application' by default. - # config.http_authentication_realm = 'Application' - - # It will change confirmation, password recovery and other workflows - # to behave the same regardless if the e-mail provided was right or wrong. - # Does not affect registerable. - # config.paranoid = true - - # By default Devise will store the user in session. You can skip storage for - # particular strategies by setting this option. - # Notice that if you are skipping storage for all authentication paths, you - # may want to disable generating routes to Devise's sessions controller by - # passing skip: :sessions to `devise_for` in your config/routes.rb - config.skip_session_storage = [:http_auth] - - # By default, Devise cleans up the CSRF token on authentication to - # avoid CSRF token fixation attacks. This means that, when using AJAX - # requests for sign in and sign up, you need to get a new CSRF token - # from the server. You can disable this option at your own risk. - # config.clean_up_csrf_token_on_authentication = true - - # When false, Devise will not attempt to reload routes on eager load. - # This can reduce the time taken to boot the app but if your application - # requires the Devise mappings to be loaded during boot time the application - # won't boot properly. - # config.reload_routes = true - - # ==> Configuration for :database_authenticatable - # For bcrypt, this is the cost for hashing the password and defaults to 12. If - # using other algorithms, it sets how many times you want the password to be hashed. - # The number of stretches used for generating the hashed password are stored - # with the hashed password. This allows you to change the stretches without - # invalidating existing passwords. - # - # Limiting the stretches to just one in testing will increase the performance of - # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use - # a value less than 10 in other environments. Note that, for bcrypt (the default - # algorithm), the cost increases exponentially with the number of stretches (e.g. - # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). - config.stretches = Rails.env.test? ? 1 : 12 - - # Set up a pepper to generate the hashed password. - # config.pepper = '8b94639bc3aa104aa9b17554d6209cdc5bbbd767a3296f3f6600220cda59ddae62ddc13c37250d3602924f4e4d9c0e24788e318eba5c60dff77e478139388460' - - # Send a notification to the original email when the user's email is changed. - # config.send_email_changed_notification = false - - # Send a notification email when the user's password is changed. - # config.send_password_change_notification = false - - # ==> Configuration for :confirmable - # A period that the user is allowed to access the website even without - # confirming their account. For instance, if set to 2.days, the user will be - # able to access the website for two days without confirming their account, - # access will be blocked just in the third day. - # You can also set it to nil, which will allow the user to access the website - # without confirming their account. - # Default is 0.days, meaning the user cannot access the website without - # confirming their account. - # config.allow_unconfirmed_access_for = 2.days - - # A period that the user is allowed to confirm their account before their - # token becomes invalid. For example, if set to 3.days, the user can confirm - # their account within 3 days after the mail was sent, but on the fourth day - # their account can't be confirmed with the token any more. - # Default is nil, meaning there is no restriction on how long a user can take - # before confirming their account. - # config.confirm_within = 3.days - - # If true, requires any email changes to be confirmed (exactly the same way as - # initial account confirmation) to be applied. Requires additional unconfirmed_email - # db field (see migrations). Until confirmed, new email is stored in - # unconfirmed_email column, and copied to email column on successful confirmation. - config.reconfirmable = true - - # Defines which key will be used when confirming an account - # config.confirmation_keys = [:email] - - # ==> Configuration for :rememberable - # The time the user will be remembered without asking for credentials again. - # config.remember_for = 2.weeks - - # Invalidates all the remember me tokens when the user signs out. - config.expire_all_remember_me_on_sign_out = true - - # If true, extends the user's remember period when remembered via cookie. - # config.extend_remember_period = false - - # Options to be passed to the created cookie. For instance, you can set - # secure: true in order to force SSL only cookies. - # config.rememberable_options = {} - - # ==> Configuration for :validatable - # Range for password length. - config.password_length = 4..128 - - # Email regex used to validate email formats. It simply asserts that - # one (and only one) @ exists in the given string. This is mainly - # to give user feedback and not to assert the e-mail validity. - config.email_regexp = /\A[^@\s]+@[^@\s]+\z/ - - # ==> Configuration for :timeoutable - # The time you want to timeout the user session without activity. After this - # time the user will be asked for credentials again. Default is 30 minutes. - # config.timeout_in = 30.minutes - - # ==> Configuration for :lockable - # Defines which strategy will be used to lock an account. - # :failed_attempts = Locks an account after a number of failed attempts to sign in. - # :none = No lock strategy. You should handle locking by yourself. - # config.lock_strategy = :failed_attempts - - # Defines which key will be used when locking and unlocking an account - # config.unlock_keys = [:email] - - # Defines which strategy will be used to unlock an account. - # :email = Sends an unlock link to the user email - # :time = Re-enables login after a certain amount of time (see :unlock_in below) - # :both = Enables both strategies - # :none = No unlock strategy. You should handle unlocking by yourself. - # config.unlock_strategy = :both - - # Number of authentication tries before locking an account if lock_strategy - # is failed attempts. - # config.maximum_attempts = 20 - - # Time interval to unlock the account if :time is enabled as unlock_strategy. - # config.unlock_in = 1.hour - - # Warn on the last attempt before the account is locked. - # config.last_attempt_warning = true - - # ==> Configuration for :recoverable - # - # Defines which key will be used when recovering the password for an account - # config.reset_password_keys = [:email] - - # Time interval you can reset your password with a reset password key. - # Don't put a too small interval or your users won't have the time to - # change their passwords. - config.reset_password_within = 6.hours - - # When set to false, does not sign a user in automatically after their password is - # reset. Defaults to true, so a user is signed in automatically after a reset. - # config.sign_in_after_reset_password = true - - # ==> Configuration for :encryptable - # Allow you to use another hashing or encryption algorithm besides bcrypt (default). - # You can use :sha1, :sha512 or algorithms from others authentication tools as - # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20 - # for default behavior) and :restful_authentication_sha1 (then you should set - # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper). - # - # Require the `devise-encryptable` gem when using anything other than bcrypt - # config.encryptor = :sha512 - - # ==> Scopes configuration - # Turn scoped views on. Before rendering "sessions/new", it will first check for - # "users/sessions/new". It's turned off by default because it's slower if you - # are using only default views. - # config.scoped_views = false - - # Configure the default scope given to Warden. By default it's the first - # devise role declared in your routes (usually :user). - # config.default_scope = :user - - # Set this configuration to false if you want /users/sign_out to sign out - # only the current scope. By default, Devise signs out all scopes. - # config.sign_out_all_scopes = true - - # ==> Navigation configuration - # Lists the formats that should be treated as navigational. Formats like - # :html should redirect to the sign in page when the user does not have - # access, but formats like :xml or :json, should return 401. - # - # If you have any extra navigational formats, like :iphone or :mobile, you - # should add them to the navigational formats lists. - # - # The "*/*" below is required to match Internet Explorer requests. - # config.navigational_formats = ['*/*', :html, :turbo_stream] - - # The default HTTP method used to sign out a resource. Default is :delete. - config.sign_out_via = :delete - - # ==> OmniAuth - # Add a new OmniAuth provider. Check the wiki for more information on setting - # up on your models and hooks. - # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' - - # ==> Warden configuration - # If you want to use other strategies, that are not supported by Devise, or - # change the failure app, you can configure them inside the config.warden block. - # - # config.warden do |manager| - # manager.intercept_401 = false - # manager.default_strategies(scope: :user).unshift :some_external_strategy - # end - - # ==> Mountable engine configurations - # When using Devise inside an engine, let's call it `MyEngine`, and this engine - # is mountable, there are some extra configurations to be taken into account. - # The following options are available, assuming the engine is mounted as: - # - # mount MyEngine, at: '/my_engine' - # - # The router that invoked `devise_for`, in the example above, would be: - # config.router_name = :my_engine - # - # When using OmniAuth, Devise cannot automatically set OmniAuth path, - # so you need to do it manually. For the users scope, it would be: - # config.omniauth_path_prefix = '/my_engine/users/auth' - - # ==> Configuration for :registerable - - # When set to false, does not sign a user in automatically after their password is - # changed. Defaults to true, so a user is signed in automatically after changing a password. - # config.sign_in_after_change_password = true -end diff --git a/utils/build/docker/ruby/rails40/config/initializers/filter_parameter_logging.rb b/utils/build/docker/ruby/rails40/config/initializers/filter_parameter_logging.rb deleted file mode 100644 index 4a994e1e7bb..00000000000 --- a/utils/build/docker/ruby/rails40/config/initializers/filter_parameter_logging.rb +++ /dev/null @@ -1,4 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Configure sensitive parameters which will be filtered from the log file. -Rails.application.config.filter_parameters += [:password] diff --git a/utils/build/docker/ruby/rails40/config/initializers/inflections.rb b/utils/build/docker/ruby/rails40/config/initializers/inflections.rb deleted file mode 100644 index ac033bf9dc8..00000000000 --- a/utils/build/docker/ruby/rails40/config/initializers/inflections.rb +++ /dev/null @@ -1,16 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new inflection rules using the following format. Inflections -# are locale specific, and you may define rules for as many different -# locales as you wish. All of these examples are active by default: -# ActiveSupport::Inflector.inflections(:en) do |inflect| -# inflect.plural /^(ox)$/i, '\1en' -# inflect.singular /^(ox)en/i, '\1' -# inflect.irregular 'person', 'people' -# inflect.uncountable %w( fish sheep ) -# end - -# These inflection rules are supported but not enabled by default: -# ActiveSupport::Inflector.inflections(:en) do |inflect| -# inflect.acronym 'RESTful' -# end diff --git a/utils/build/docker/ruby/rails40/config/initializers/mime_types.rb b/utils/build/docker/ruby/rails40/config/initializers/mime_types.rb deleted file mode 100644 index 72aca7e441e..00000000000 --- a/utils/build/docker/ruby/rails40/config/initializers/mime_types.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new mime types for use in respond_to blocks: -# Mime::Type.register "text/richtext", :rtf -# Mime::Type.register_alias "text/html", :iphone diff --git a/utils/build/docker/ruby/rails40/config/initializers/secret_token.rb b/utils/build/docker/ruby/rails40/config/initializers/secret_token.rb deleted file mode 100644 index 8bd8ba21304..00000000000 --- a/utils/build/docker/ruby/rails40/config/initializers/secret_token.rb +++ /dev/null @@ -1,12 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Your secret key is used for verifying the integrity of signed cookies. -# If you change this key, all old signed cookies will become invalid! - -# Make sure the secret is at least 30 characters and all random, -# no regular words or you'll be exposed to dictionary attacks. -# You can use `rake secret` to generate a secure secret key. - -# Make sure your secret_key_base is kept private -# if you're sharing your code publicly. -Rails40::Application.config.secret_key_base = '6768a49d36f5965b7bf408e833e54459f7dd0abffafabc7d6954946f1297e950031b503e5f44a005d18f0ccfc7591263c39f9aae11e428283feebb4e6162ba83' diff --git a/utils/build/docker/ruby/rails40/config/initializers/session_store.rb b/utils/build/docker/ruby/rails40/config/initializers/session_store.rb deleted file mode 100644 index be304b258a5..00000000000 --- a/utils/build/docker/ruby/rails40/config/initializers/session_store.rb +++ /dev/null @@ -1,3 +0,0 @@ -# Be sure to restart your server when you modify this file. - -Rails40::Application.config.session_store :cookie_store, key: '_rails40_session' diff --git a/utils/build/docker/ruby/rails40/config/initializers/wrap_parameters.rb b/utils/build/docker/ruby/rails40/config/initializers/wrap_parameters.rb deleted file mode 100644 index 33725e95fd2..00000000000 --- a/utils/build/docker/ruby/rails40/config/initializers/wrap_parameters.rb +++ /dev/null @@ -1,14 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# This file contains settings for ActionController::ParamsWrapper which -# is enabled by default. - -# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. -ActiveSupport.on_load(:action_controller) do - wrap_parameters format: [:json] if respond_to?(:wrap_parameters) -end - -# To enable root element in JSON for ActiveRecord objects. -# ActiveSupport.on_load(:active_record) do -# self.include_root_in_json = true -# end diff --git a/utils/build/docker/ruby/rails40/config/locales/en.yml b/utils/build/docker/ruby/rails40/config/locales/en.yml deleted file mode 100644 index 0653957166e..00000000000 --- a/utils/build/docker/ruby/rails40/config/locales/en.yml +++ /dev/null @@ -1,23 +0,0 @@ -# Files in the config/locales directory are used for internationalization -# and are automatically loaded by Rails. If you want to use locales other -# than English, add the necessary files in this directory. -# -# To use the locales, use `I18n.t`: -# -# I18n.t 'hello' -# -# In views, this is aliased to just `t`: -# -# <%= t('hello') %> -# -# To use a different locale, set it with `I18n.locale`: -# -# I18n.locale = :es -# -# This would use the information in config/locales/es.yml. -# -# To learn more, please read the Rails Internationalization guide -# available at http://guides.rubyonrails.org/i18n.html. - -en: - hello: "Hello world" diff --git a/utils/build/docker/ruby/rails40/config/routes.rb b/utils/build/docker/ruby/rails40/config/routes.rb deleted file mode 100644 index ebaf9080a65..00000000000 --- a/utils/build/docker/ruby/rails40/config/routes.rb +++ /dev/null @@ -1,35 +0,0 @@ -Rails40::Application.routes.draw do - get '/' => 'system_test#root' - post '/' => 'system_test#root' - - get '/waf' => 'system_test#waf' - post '/waf' => 'system_test#waf' - get '/waf/*other' => 'system_test#waf' - post '/waf/*other' => 'system_test#waf' - - get '/params/:value' => 'system_test#handle_path_params' - get '/spans' => 'system_test#generate_spans' - get '/status' => 'system_test#status' - get '/make_distant_call' => 'system_test#make_distant_call' - - get '/headers' => 'system_test#test_headers' - get '/identify' => 'system_test#identify' - - get 'user_login_success_event' => 'system_test#user_login_success_event' - get 'user_login_failure_event' => 'system_test#user_login_failure_event' - get 'custom_event' => 'system_test#custom_event' - - %i(get post).each do |request_method| - send(request_method, '/tag_value/:tag_value/:status_code' => 'system_test#tag_value') - end - match '/tag_value/:tag_value/:status_code' => 'system_test#tag_value', via: :options - get '/users' => 'system_test#users' - - devise_for :users - %i(get post).each do |request_method| - # We have to provide format: false to make sure the Test_DiscoveryScan test do not break - # https://github.com/DataDog/system-tests/blob/6873c9577ddc15693a98f9683075a1b9d4e587f0/tests/appsec/waf/test_rules.py#L374 - # The test hits '/login.pwd' and expects a 404. By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists - send(request_method, '/login' => 'system_test#login', format: false) - end -end diff --git a/utils/build/docker/ruby/rails40/db/migrate/20230621141816_devise_create_users.rb b/utils/build/docker/ruby/rails40/db/migrate/20230621141816_devise_create_users.rb deleted file mode 100644 index 992282a81cc..00000000000 --- a/utils/build/docker/ruby/rails40/db/migrate/20230621141816_devise_create_users.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -class DeviseCreateUsers < ActiveRecord::Migration - def change - create_table :users, id: :string do |t| - ## Database authenticatable - t.string :username, null: false, default: "" - t.string :email, null: false, default: "" - t.string :encrypted_password, null: false, default: "" - - ## Recoverable - t.string :reset_password_token - t.datetime :reset_password_sent_at - - ## Rememberable - t.datetime :remember_created_at - - ## Trackable - # t.integer :sign_in_count, default: 0, null: false - # t.datetime :current_sign_in_at - # t.datetime :last_sign_in_at - # t.string :current_sign_in_ip - # t.string :last_sign_in_ip - - ## Confirmable - # t.string :confirmation_token - # t.datetime :confirmed_at - # t.datetime :confirmation_sent_at - # t.string :unconfirmed_email # Only if using reconfirmable - - ## Lockable - # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts - # t.string :unlock_token # Only if unlock strategy is :email or :both - # t.datetime :locked_at - - - t.timestamps null: false - end - - add_index :users, :email, unique: true - add_index :users, :reset_password_token, unique: true - # add_index :users, :confirmation_token, unique: true - # add_index :users, :unlock_token, unique: true - end -end diff --git a/utils/build/docker/ruby/rails40/public/404.html b/utils/build/docker/ruby/rails40/public/404.html deleted file mode 100644 index a0daa0c1567..00000000000 --- a/utils/build/docker/ruby/rails40/public/404.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - The page you were looking for doesn't exist (404) - - - - - -
-

The page you were looking for doesn't exist.

-

You may have mistyped the address or the page may have moved.

-
-

If you are the application owner check the logs for more information.

- - diff --git a/utils/build/docker/ruby/rails40/public/422.html b/utils/build/docker/ruby/rails40/public/422.html deleted file mode 100644 index fbb4b84d725..00000000000 --- a/utils/build/docker/ruby/rails40/public/422.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - The change you wanted was rejected (422) - - - - - -
-

The change you wanted was rejected.

-

Maybe you tried to change something you didn't have access to.

-
-

If you are the application owner check the logs for more information.

- - diff --git a/utils/build/docker/ruby/rails40/public/500.html b/utils/build/docker/ruby/rails40/public/500.html deleted file mode 100644 index e9052d35bfb..00000000000 --- a/utils/build/docker/ruby/rails40/public/500.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - We're sorry, but something went wrong (500) - - - - - -
-

We're sorry, but something went wrong.

-
-

If you are the application owner check the logs for more information.

- - diff --git a/utils/build/docker/ruby/rails40/public/robots.txt b/utils/build/docker/ruby/rails40/public/robots.txt deleted file mode 100644 index 3c9c7c01f30..00000000000 --- a/utils/build/docker/ruby/rails40/public/robots.txt +++ /dev/null @@ -1,5 +0,0 @@ -# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file -# -# To ban all spiders from the entire site uncomment the next two lines: -# User-agent: * -# Disallow: / diff --git a/utils/build/docker/ruby/rails40/test/test_helper.rb b/utils/build/docker/ruby/rails40/test/test_helper.rb deleted file mode 100644 index bc7e05d7054..00000000000 --- a/utils/build/docker/ruby/rails40/test/test_helper.rb +++ /dev/null @@ -1,15 +0,0 @@ -ENV["RAILS_ENV"] ||= "test" -require File.expand_path('../../config/environment', __FILE__) -require 'rails/test_help' - -class ActiveSupport::TestCase - ActiveRecord::Migration.check_pending! - - # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. - # - # Note: You'll currently still have to declare fixtures explicitly in integration tests - # -- they do not yet inherit this setting - fixtures :all - - # Add more helper methods to be used by all tests here... -end diff --git a/utils/build/docker/ruby/rails41.Dockerfile b/utils/build/docker/ruby/rails41.Dockerfile deleted file mode 100644 index a59fa071544..00000000000 --- a/utils/build/docker/ruby/rails41.Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:2.3.8-dd - -RUN mkdir -p /app -WORKDIR /app - -RUN curl -O https://rubygems.org/downloads/libv8-node-15.14.0.1-$(arch)-linux.gem && gem install libv8-node-15.14.0.1-$(arch)-linux.gem && rm libv8-node-15.14.0.1-$(arch)-linux.gem - -COPY utils/build/docker/ruby/rails41/ . - -COPY utils/build/docker/ruby/install_ddtrace.sh binaries* /binaries/ -RUN /binaries/install_ddtrace.sh - -ENV DD_TRACE_HEADER_TAGS=user-agent -ENV RAILS_ENV=production -ENV SECRET_KEY_BASE=e4d6dd9246d5d2fe497f8985074ca9bc698f6d889b8d1e04eb46442d439ff85a8ce3e5c8b776ed998d7be5d705a1069ec6a5999da0d5ca52f3c54f18cc2b7223 -RUN bundle exec rake db:create db:migrate db:seed - -RUN echo "#!/bin/bash\nbundle exec puma -b tcp://0.0.0.0 -p 7777 -w 1" > app.sh -RUN chmod +x app.sh -CMD [ "./app.sh" ] - diff --git a/utils/build/docker/ruby/rails41/.dockerignore b/utils/build/docker/ruby/rails41/.dockerignore deleted file mode 100644 index 209439b011e..00000000000 --- a/utils/build/docker/ruby/rails41/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -.envrc -shell.nix -vendor/bundle diff --git a/utils/build/docker/ruby/rails41/.gitignore b/utils/build/docker/ruby/rails41/.gitignore deleted file mode 100644 index 6a502e997fe..00000000000 --- a/utils/build/docker/ruby/rails41/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -# See https://help.github.com/articles/ignoring-files for more about ignoring files. -# -# If you find yourself ignoring temporary files generated by your text editor -# or operating system, you probably want to add a global ignore instead: -# git config --global core.excludesfile '~/.gitignore_global' - -# Ignore bundler config. -/.bundle - -# Ignore the default SQLite database. -/db/*.sqlite3 -/db/*.sqlite3-journal - -# Ignore all logfiles and tempfiles. -/log/*.log -/tmp diff --git a/utils/build/docker/ruby/rails41/Gemfile b/utils/build/docker/ruby/rails41/Gemfile deleted file mode 100644 index 5e11698db8d..00000000000 --- a/utils/build/docker/ruby/rails41/Gemfile +++ /dev/null @@ -1,46 +0,0 @@ -source 'https://rubygems.org' - - -# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '4.1.16' -# Use sqlite3 as the database for Active Record -gem 'sqlite3', '< 1.4' -# Use SCSS for stylesheets -gem 'sass-rails', '~> 4.0.3' -# Use Uglifier as compressor for JavaScript assets -gem 'uglifier', '>= 1.3.0' -# Use CoffeeScript for .js.coffee assets and views -gem 'coffee-rails', '~> 4.0.0' -# See https://github.com/rails/execjs#readme for more supported runtimes -# gem 'therubyracer', platforms: :ruby - -# Use jquery as the JavaScript library -gem 'jquery-rails' -# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks -gem 'turbolinks' -# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder -gem 'jbuilder', '~> 2.0' -# bundle exec rake doc:rails generates the API under doc/api. -gem 'sdoc', '~> 0.4.0', group: :doc - -# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring -gem 'spring', group: :development - -# Use ActiveModel has_secure_password -# gem 'bcrypt', '~> 3.1.7' - -# Use unicorn as the app server -# gem 'unicorn' - -# Use Capistrano for deployment -# gem 'capistrano-rails', group: :development - -# Use debugger -# gem 'debugger', group: [:development, :test] - -gem 'pry' -gem 'devise' -gem 'ddtrace', '~> 1.0.0.a', require: 'ddtrace/auto_instrument' -gem 'msgpack', '~> 1.3.3' # Ruby < 2.4 -gem 'mini_racer', '~> 0.4.0', platforms: :ruby -gem 'puma' diff --git a/utils/build/docker/ruby/rails41/Gemfile.lock b/utils/build/docker/ruby/rails41/Gemfile.lock deleted file mode 100644 index 09f8e0e93d3..00000000000 --- a/utils/build/docker/ruby/rails41/Gemfile.lock +++ /dev/null @@ -1,174 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - actionmailer (4.1.16) - actionpack (= 4.1.16) - actionview (= 4.1.16) - mail (~> 2.5, >= 2.5.4) - actionpack (4.1.16) - actionview (= 4.1.16) - activesupport (= 4.1.16) - rack (~> 1.5.2) - rack-test (~> 0.6.2) - actionview (4.1.16) - activesupport (= 4.1.16) - builder (~> 3.1) - erubis (~> 2.7.0) - activemodel (4.1.16) - activesupport (= 4.1.16) - builder (~> 3.1) - activerecord (4.1.16) - activemodel (= 4.1.16) - activesupport (= 4.1.16) - arel (~> 5.0.0) - activesupport (4.1.16) - i18n (~> 0.6, >= 0.6.9) - json (~> 1.7, >= 1.7.7) - minitest (~> 5.1) - thread_safe (~> 0.1) - tzinfo (~> 1.1) - arel (5.0.1.20140414130214) - bcrypt (3.1.20) - builder (3.2.4) - coderay (1.1.3) - coffee-rails (4.0.1) - coffee-script (>= 2.2.0) - railties (>= 4.0.0, < 5.0) - coffee-script (2.4.1) - coffee-script-source - execjs - coffee-script-source (1.12.2) - concurrent-ruby (1.1.9) - ddtrace (1.0.0.beta1) - debase-ruby_core_source (<= 0.10.14) - libddwaf (~> 1.0.14.2.0.a) - msgpack - debase-ruby_core_source (0.10.14) - devise (4.9.3) - bcrypt (~> 3.0) - orm_adapter (~> 0.1) - railties (>= 4.1.0) - responders - warden (~> 1.2.3) - erubis (2.7.0) - execjs (2.8.1) - ffi (1.15.5) - hike (1.2.3) - i18n (0.9.5) - concurrent-ruby (~> 1.0) - jbuilder (2.6.4) - activesupport (>= 3.0.0) - multi_json (>= 1.2) - jquery-rails (3.1.5) - railties (>= 3.0, < 5.0) - thor (>= 0.14, < 2.0) - json (1.8.6) - libddwaf (1.0.14.2.0.beta1) - ffi (~> 1.0) - libddwaf (1.0.14.2.0.beta1-aarch64-linux) - ffi (~> 1.0) - libddwaf (1.0.14.2.0.beta1-arm64-darwin) - ffi (~> 1.0) - libddwaf (1.0.14.2.0.beta1-x86_64-darwin) - ffi (~> 1.0) - libddwaf (1.0.14.2.0.beta1-x86_64-linux) - ffi (~> 1.0) - libv8-node (15.14.0.1) - mail (2.7.1) - mini_mime (>= 0.1.1) - method_source (1.0.0) - mini_mime (1.1.2) - mini_racer (0.4.0) - libv8-node (~> 15.14.0.0) - minitest (5.15.0) - msgpack (1.3.3) - multi_json (1.15.0) - nio4r (2.5.2) - orm_adapter (0.5.0) - pry (0.14.1) - coderay (~> 1.1) - method_source (~> 1.0) - puma (5.6.1) - nio4r (~> 2.0) - rack (1.5.5) - rack-test (0.6.3) - rack (>= 1.0) - rails (4.1.16) - actionmailer (= 4.1.16) - actionpack (= 4.1.16) - actionview (= 4.1.16) - activemodel (= 4.1.16) - activerecord (= 4.1.16) - activesupport (= 4.1.16) - bundler (>= 1.3.0, < 2.0) - railties (= 4.1.16) - sprockets-rails (~> 2.0) - railties (4.1.16) - actionpack (= 4.1.16) - activesupport (= 4.1.16) - rake (>= 0.8.7) - thor (>= 0.18.1, < 2.0) - rake (13.0.6) - rdoc (4.3.0) - responders (1.1.2) - railties (>= 3.2, < 4.2) - sass (3.2.19) - sass-rails (4.0.5) - railties (>= 4.0.0, < 5.0) - sass (~> 3.2.2) - sprockets (~> 2.8, < 3.0) - sprockets-rails (~> 2.0) - sdoc (0.4.2) - json (~> 1.7, >= 1.7.7) - rdoc (~> 4.0) - spring (1.7.2) - sprockets (2.12.5) - hike (~> 1.2) - multi_json (~> 1.0) - rack (~> 1.0) - tilt (~> 1.1, != 1.3.0) - sprockets-rails (2.3.3) - actionpack (>= 3.0) - activesupport (>= 3.0) - sprockets (>= 2.8, < 4.0) - sqlite3 (1.3.13) - thor (1.2.1) - thread_safe (0.3.6) - tilt (1.4.1) - turbolinks (5.2.1) - turbolinks-source (~> 5.2) - turbolinks-source (5.2.0) - tzinfo (1.2.9) - thread_safe (~> 0.1) - uglifier (4.2.0) - execjs (>= 0.3.0, < 3) - warden (1.2.7) - rack (>= 1.0) - -PLATFORMS - aarch64-linux - arm64-darwin - ruby - x86_64-darwin - x86_64-linux - -DEPENDENCIES - coffee-rails (~> 4.0.0) - ddtrace (~> 1.0.0.a) - devise - jbuilder (~> 2.0) - jquery-rails - mini_racer (~> 0.4.0) - msgpack (~> 1.3.3) - pry - puma - rails (= 4.1.16) - sass-rails (~> 4.0.3) - sdoc (~> 0.4.0) - spring - sqlite3 (< 1.4) - turbolinks - uglifier (>= 1.3.0) - -BUNDLED WITH - 1.17.3 diff --git a/utils/build/docker/ruby/rails41/README.rdoc b/utils/build/docker/ruby/rails41/README.rdoc deleted file mode 100644 index dd4e97e22e1..00000000000 --- a/utils/build/docker/ruby/rails41/README.rdoc +++ /dev/null @@ -1,28 +0,0 @@ -== README - -This README would normally document whatever steps are necessary to get the -application up and running. - -Things you may want to cover: - -* Ruby version - -* System dependencies - -* Configuration - -* Database creation - -* Database initialization - -* How to run the test suite - -* Services (job queues, cache servers, search engines, etc.) - -* Deployment instructions - -* ... - - -Please feel free to use a different markup language if you do not plan to run -rake doc:app. diff --git a/utils/build/docker/ruby/rails41/Rakefile b/utils/build/docker/ruby/rails41/Rakefile deleted file mode 100644 index ba6b733dd23..00000000000 --- a/utils/build/docker/ruby/rails41/Rakefile +++ /dev/null @@ -1,6 +0,0 @@ -# Add your own tasks in files placed in lib/tasks ending in .rake, -# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. - -require File.expand_path('../config/application', __FILE__) - -Rails.application.load_tasks diff --git a/utils/build/docker/ruby/rails41/app/assets/javascripts/application.js b/utils/build/docker/ruby/rails41/app/assets/javascripts/application.js deleted file mode 100644 index b7b6c86c34b..00000000000 --- a/utils/build/docker/ruby/rails41/app/assets/javascripts/application.js +++ /dev/null @@ -1,16 +0,0 @@ -// This is a manifest file that'll be compiled into application.js, which will include all the files -// listed below. -// -// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, -// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. -// -// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the -// compiled file. -// -// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details -// about supported directives. -// -//= require jquery -//= require jquery_ujs -//= require turbolinks -//= require_tree . diff --git a/utils/build/docker/ruby/rails41/app/assets/stylesheets/application.css b/utils/build/docker/ruby/rails41/app/assets/stylesheets/application.css deleted file mode 100644 index a443db34012..00000000000 --- a/utils/build/docker/ruby/rails41/app/assets/stylesheets/application.css +++ /dev/null @@ -1,15 +0,0 @@ -/* - * This is a manifest file that'll be compiled into application.css, which will include all the files - * listed below. - * - * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, - * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. - * - * You're free to add application-wide styles to this file and they'll appear at the bottom of the - * compiled file so the styles you add here take precedence over styles defined in any styles - * defined in the other CSS/SCSS files in this directory. It is generally better to create a new - * file per style scope. - * - *= require_tree . - *= require_self - */ diff --git a/utils/build/docker/ruby/rails41/app/controllers/application_controller.rb b/utils/build/docker/ruby/rails41/app/controllers/application_controller.rb deleted file mode 100644 index d83690e1b9a..00000000000 --- a/utils/build/docker/ruby/rails41/app/controllers/application_controller.rb +++ /dev/null @@ -1,5 +0,0 @@ -class ApplicationController < ActionController::Base - # Prevent CSRF attacks by raising an exception. - # For APIs, you may want to use :null_session instead. - protect_from_forgery with: :exception -end diff --git a/utils/build/docker/ruby/rails41/app/controllers/system_test_controller.rb b/utils/build/docker/ruby/rails41/app/controllers/system_test_controller.rb deleted file mode 100644 index a911b62b67a..00000000000 --- a/utils/build/docker/ruby/rails41/app/controllers/system_test_controller.rb +++ /dev/null @@ -1,168 +0,0 @@ -require 'datadog/kit/appsec/events' - -class SystemTestController < ApplicationController - skip_before_action :verify_authenticity_token - - def root - render plain: 'Hello, world!' - end - - def waf - render plain: 'Hello, world!' - end - - def handle_path_params - render plain: 'Hello, world!' - end - - def generate_spans - begin - repeats = Integer(request.params['repeats'] || 0) - garbage = Integer(request.params['garbage'] || 0) - rescue ArgumentError - render plain: 'bad request', status: 400 - else - repeats.times do |i| - Datadog::Tracing.trace('repeat-#{i}') do |span| - garbage.times do |j| - span.set_tag("garbage-#{j}", "#{j}") - end - end - end - end - - render plain: 'Generated #{repeats} spans with #{garbage} garbage tags' - end - - def test_headers - response.headers['Content-Type'] ='text/plain' - response.headers['Content-Length'] ='15' - response.headers['Content-Language'] ='en-US' - - render plain: 'Hello, headers!' - end - - def identify - trace = Datadog::Tracing.active_trace - trace.set_tag('usr.id', 'usr.id') - trace.set_tag('usr.name', 'usr.name') - trace.set_tag('usr.email', 'usr.email') - trace.set_tag('usr.session_id', 'usr.session_id') - trace.set_tag('usr.role', 'usr.role') - trace.set_tag('usr.scope', 'usr.scope') - - render plain: 'Hello, world!' - end - - - def status - render plain: "Ok", status: params[:code] - end - - def make_distant_call - url = params[:url] - uri = URI(url) - request = nil - response = nil - - Net::HTTP.start(uri.host, uri.port) do |http| - request = Net::HTTP::Get.new(uri) - - response = http.request(request) - end - - result = { - "url": url, - "status_code": response.code, - "request_headers": request.each_header.to_h, - "response_headers": response.each_header.to_h, - } - - render json: result - end - - def user_login_success_event - Datadog::Kit::AppSec::Events.track_login_success( - Datadog::Tracing.active_trace, user: {id: 'system_tests_user'}, metadata0: "value0", metadata1: "value1" - ) - - render plain: 'Hello, world!' - end - - def user_login_failure_event - Datadog::Kit::AppSec::Events.track_login_failure( - Datadog::Tracing.active_trace, user_id: 'system_tests_user', user_exists: true, metadata0: "value0", metadata1: "value1" - ) - - render plain: 'Hello, world!' - end - - def custom_event - Datadog::Kit::AppSec::Events.track('system_tests_event', Datadog::Tracing.active_trace, metadata0: "value0", metadata1: "value1") - - render plain: 'Hello, world!' - end - - def tag_value - event_value = params[:tag_value] - status_code = params[:status_code] - - if request.method == "POST" && event_value.include?('payload_in_response_body') - render json: { payload: request.POST } - return - end - - headers = request.query_string.split('&').map {|e | e.split('=')} || [] - - trace = Datadog::Tracing.active_trace - trace.set_tag("appsec.events.system_tests_appsec_event.value", event_value) - - headers.each do |key, value| - response.headers[key] = value - end - - render plain: 'Value tagged', status: status_code - end - - def users - user_id = request.params["user"] - - Datadog::Kit::Identity.set_user(id: user_id) - - render plain: 'Hello, user!' - end - - def login - request.env["devise.allow_params_authentication"] = true - - sdk_event = request.params[:sdk_event] - sdk_user = request.params[:sdk_user] - sdk_email = request.params[:sdk_mail] - sdk_exists = request.params[:sdk_user_exists] - - if sdk_exists - sdk_exists = sdk_exists == "true" - end - - result = request.env['warden'].authenticate({ scope: Devise.mappings[:user].name }) - - if sdk_event === 'failure' && sdk_user - metadata = {} - metadata[:email] = sdk_email if sdk_email - Datadog::Kit::AppSec::Events.track_login_failure(user_id: sdk_user, user_exists: sdk_exists, **metadata) - elsif sdk_event === 'success' && sdk_user - user = {} - user[:id] = sdk_user - user[:email] = sdk_email if sdk_email - Datadog::Kit::AppSec::Events.track_login_success(user: user) - end - - unless result - render plain: '', status: 401 - return - end - - - render plain: 'Hello, world!' - end -end diff --git a/utils/build/docker/ruby/rails41/app/models/user.rb b/utils/build/docker/ruby/rails41/app/models/user.rb deleted file mode 100644 index 634e20d9a7a..00000000000 --- a/utils/build/docker/ruby/rails41/app/models/user.rb +++ /dev/null @@ -1,6 +0,0 @@ -class User < ActiveRecord::Base - # Include default devise modules. Others available are: - # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable - devise :database_authenticatable, :registerable, - :recoverable, :rememberable, :validatable -end diff --git a/utils/build/docker/ruby/rails41/app/views/layouts/application.html.erb b/utils/build/docker/ruby/rails41/app/views/layouts/application.html.erb deleted file mode 100644 index 191ac3c1917..00000000000 --- a/utils/build/docker/ruby/rails41/app/views/layouts/application.html.erb +++ /dev/null @@ -1,14 +0,0 @@ - - - - Rails41 - <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> - <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> - <%= csrf_meta_tags %> - - - -<%= yield %> - - - diff --git a/utils/build/docker/ruby/rails41/config.ru b/utils/build/docker/ruby/rails41/config.ru deleted file mode 100644 index 5bc2a619e83..00000000000 --- a/utils/build/docker/ruby/rails41/config.ru +++ /dev/null @@ -1,4 +0,0 @@ -# This file is used by Rack-based servers to start the application. - -require ::File.expand_path('../config/environment', __FILE__) -run Rails.application diff --git a/utils/build/docker/ruby/rails41/config/application.rb b/utils/build/docker/ruby/rails41/config/application.rb deleted file mode 100644 index b0b2111ab75..00000000000 --- a/utils/build/docker/ruby/rails41/config/application.rb +++ /dev/null @@ -1,27 +0,0 @@ -require File.expand_path('../boot', __FILE__) - -require 'rails/all' - -# Require the gems listed in Gemfile, including any gems -# you've limited to :test, :development, or :production. -Bundler.require(*Rails.groups) - -module Rails41 - class Application < Rails::Application - # Settings in config/environments/* take precedence over those specified here. - # Application configuration should go into files in config/initializers - # -- all .rb files in that directory are automatically loaded. - - # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. - # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. - # config.time_zone = 'Central Time (US & Canada)' - - # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. - # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] - # config.i18n.default_locale = :de - # - # With Rails 4 there is an issue with the Rack::Lock middleware - # For more information check https://github.com/rails/rails/issues/20660 - config.middleware.delete Rack::Lock - end -end diff --git a/utils/build/docker/ruby/rails41/config/boot.rb b/utils/build/docker/ruby/rails41/config/boot.rb deleted file mode 100644 index 5e5f0c1fac0..00000000000 --- a/utils/build/docker/ruby/rails41/config/boot.rb +++ /dev/null @@ -1,4 +0,0 @@ -# Set up gems listed in the Gemfile. -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) - -require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) diff --git a/utils/build/docker/ruby/rails41/config/database.yml b/utils/build/docker/ruby/rails41/config/database.yml deleted file mode 100644 index 1c1a37ca8df..00000000000 --- a/utils/build/docker/ruby/rails41/config/database.yml +++ /dev/null @@ -1,25 +0,0 @@ -# SQLite version 3.x -# gem install sqlite3 -# -# Ensure the SQLite 3 gem is defined in your Gemfile -# gem 'sqlite3' -# -default: &default - adapter: sqlite3 - pool: 5 - timeout: 5000 - -development: - <<: *default - database: db/development.sqlite3 - -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. -test: - <<: *default - database: db/test.sqlite3 - -production: - <<: *default - database: db/production.sqlite3 diff --git a/utils/build/docker/ruby/rails41/config/environment.rb b/utils/build/docker/ruby/rails41/config/environment.rb deleted file mode 100644 index ee8d90dc651..00000000000 --- a/utils/build/docker/ruby/rails41/config/environment.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Load the Rails application. -require File.expand_path('../application', __FILE__) - -# Initialize the Rails application. -Rails.application.initialize! diff --git a/utils/build/docker/ruby/rails41/config/environments/development.rb b/utils/build/docker/ruby/rails41/config/environments/development.rb deleted file mode 100644 index ddf0e90cc42..00000000000 --- a/utils/build/docker/ruby/rails41/config/environments/development.rb +++ /dev/null @@ -1,37 +0,0 @@ -Rails.application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # In the development environment your application's code is reloaded on - # every request. This slows down response time but is perfect for development - # since you don't have to restart the web server when you make code changes. - config.cache_classes = false - - # Do not eager load code on boot. - config.eager_load = false - - # Show full error reports and disable caching. - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - - # Don't care if the mailer can't send. - config.action_mailer.raise_delivery_errors = false - - # Print deprecation notices to the Rails logger. - config.active_support.deprecation = :log - - # Raise an error on page load if there are pending migrations. - config.active_record.migration_error = :page_load - - # Debug mode disables concatenation and preprocessing of assets. - # This option may cause significant delays in view rendering with a large - # number of complex assets. - config.assets.debug = true - - # Adds additional error checking when serving assets at runtime. - # Checks for improperly declared sprockets dependencies. - # Raises helpful error messages. - config.assets.raise_runtime_errors = true - - # Raises error for missing translations - # config.action_view.raise_on_missing_translations = true -end diff --git a/utils/build/docker/ruby/rails41/config/environments/production.rb b/utils/build/docker/ruby/rails41/config/environments/production.rb deleted file mode 100644 index b93a877c446..00000000000 --- a/utils/build/docker/ruby/rails41/config/environments/production.rb +++ /dev/null @@ -1,78 +0,0 @@ -Rails.application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # Code is not reloaded between requests. - config.cache_classes = true - - # Eager load code on boot. This eager loads most of Rails and - # your application in memory, allowing both threaded web servers - # and those relying on copy on write to perform better. - # Rake tasks automatically ignore this option for performance. - config.eager_load = true - - # Full error reports are disabled and caching is turned on. - config.consider_all_requests_local = false - config.action_controller.perform_caching = true - - # Enable Rack::Cache to put a simple HTTP cache in front of your application - # Add `rack-cache` to your Gemfile before enabling this. - # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid. - # config.action_dispatch.rack_cache = true - - # Disable Rails's static asset server (Apache or nginx will already do this). - config.serve_static_assets = false - - # Compress JavaScripts and CSS. - config.assets.js_compressor = :uglifier - # config.assets.css_compressor = :sass - - # Do not fallback to assets pipeline if a precompiled asset is missed. - config.assets.compile = false - - # Generate digests for assets URLs. - config.assets.digest = true - - # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb - - # Specifies the header that your server uses for sending files. - # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache - # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx - - # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - # config.force_ssl = true - - # Set to :debug to see everything in the log. - config.log_level = :info - - # Prepend all log lines with the following tags. - # config.log_tags = [ :subdomain, :uuid ] - - # Use a different logger for distributed setups. - # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) - - # Use a different cache store in production. - # config.cache_store = :mem_cache_store - - # Enable serving of images, stylesheets, and JavaScripts from an asset server. - # config.action_controller.asset_host = "http://assets.example.com" - - # Ignore bad email addresses and do not raise email delivery errors. - # Set this to true and configure the email server for immediate delivery to raise delivery errors. - # config.action_mailer.raise_delivery_errors = false - - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to - # the I18n.default_locale when a translation cannot be found). - config.i18n.fallbacks = true - - # Send deprecation notices to registered listeners. - config.active_support.deprecation = :notify - - # Disable automatic flushing of the log to improve performance. - # config.autoflush_log = false - - # Use default logging formatter so that PID and timestamp are not suppressed. - config.log_formatter = ::Logger::Formatter.new - - # Do not dump schema after migrations. - config.active_record.dump_schema_after_migration = false -end diff --git a/utils/build/docker/ruby/rails41/config/environments/test.rb b/utils/build/docker/ruby/rails41/config/environments/test.rb deleted file mode 100644 index 053f5b66d7f..00000000000 --- a/utils/build/docker/ruby/rails41/config/environments/test.rb +++ /dev/null @@ -1,39 +0,0 @@ -Rails.application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! - config.cache_classes = true - - # Do not eager load code on boot. This avoids loading your whole application - # just for the purpose of running a single test. If you are using a tool that - # preloads Rails for running tests, you may have to set it to true. - config.eager_load = false - - # Configure static asset server for tests with Cache-Control for performance. - config.serve_static_assets = true - config.static_cache_control = 'public, max-age=3600' - - # Show full error reports and disable caching. - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - - # Raise exceptions instead of rendering exception templates. - config.action_dispatch.show_exceptions = false - - # Disable request forgery protection in test environment. - config.action_controller.allow_forgery_protection = false - - # Tell Action Mailer not to deliver emails to the real world. - # The :test delivery method accumulates sent emails in the - # ActionMailer::Base.deliveries array. - config.action_mailer.delivery_method = :test - - # Print deprecation notices to the stderr. - config.active_support.deprecation = :stderr - - # Raises error for missing translations - # config.action_view.raise_on_missing_translations = true -end diff --git a/utils/build/docker/ruby/rails41/config/initializers/assets.rb b/utils/build/docker/ruby/rails41/config/initializers/assets.rb deleted file mode 100644 index d2f4ec33a63..00000000000 --- a/utils/build/docker/ruby/rails41/config/initializers/assets.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Version of your assets, change this if you want to expire all your assets. -Rails.application.config.assets.version = '1.0' - -# Precompile additional assets. -# application.js, application.css, and all non-JS/CSS in app/assets folder are already added. -# Rails.application.config.assets.precompile += %w( search.js ) diff --git a/utils/build/docker/ruby/rails41/config/initializers/backtrace_silencers.rb b/utils/build/docker/ruby/rails41/config/initializers/backtrace_silencers.rb deleted file mode 100644 index 59385cdf379..00000000000 --- a/utils/build/docker/ruby/rails41/config/initializers/backtrace_silencers.rb +++ /dev/null @@ -1,7 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. -# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } - -# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. -# Rails.backtrace_cleaner.remove_silencers! diff --git a/utils/build/docker/ruby/rails41/config/initializers/cookies_serializer.rb b/utils/build/docker/ruby/rails41/config/initializers/cookies_serializer.rb deleted file mode 100644 index 7a06a89f0f9..00000000000 --- a/utils/build/docker/ruby/rails41/config/initializers/cookies_serializer.rb +++ /dev/null @@ -1,3 +0,0 @@ -# Be sure to restart your server when you modify this file. - -Rails.application.config.action_dispatch.cookies_serializer = :json \ No newline at end of file diff --git a/utils/build/docker/ruby/rails41/config/initializers/datadog.rb b/utils/build/docker/ruby/rails41/config/initializers/datadog.rb deleted file mode 100644 index e7079ecc332..00000000000 --- a/utils/build/docker/ruby/rails41/config/initializers/datadog.rb +++ /dev/null @@ -1,11 +0,0 @@ -Datadog.configure do |c| - c.diagnostics.debug = true -end - -# Send non-web init event - -if defined?(Datadog::Tracing) - Datadog::Tracing.trace('init.service') { } -else - Datadog.tracer.trace('init.service') { } -end diff --git a/utils/build/docker/ruby/rails41/config/initializers/devise.rb b/utils/build/docker/ruby/rails41/config/initializers/devise.rb deleted file mode 100644 index a25dd104c77..00000000000 --- a/utils/build/docker/ruby/rails41/config/initializers/devise.rb +++ /dev/null @@ -1,304 +0,0 @@ -# frozen_string_literal: true - -# Assuming you have not yet modified this file, each configuration option below -# is set to its default value. Note that some are commented out while others -# are not: uncommented lines are intended to protect your configuration from -# breaking changes in upgrades (i.e., in the event that future versions of -# Devise change the default values for those options). -# -# Use this hook to configure devise mailer, warden hooks and so forth. -# Many of these configuration options can be set straight in your model. -Devise.setup do |config| - # The secret key used by Devise. Devise uses this key to generate - # random tokens. Changing this key will render invalid all existing - # confirmation, reset password and unlock tokens in the database. - # Devise will use the `secret_key_base` as its `secret_key` - # by default. You can change it below and use your own secret key. - # config.secret_key = '2aa7763a03b8aeefb5507ab110519240bbd9c017f8c15c8e5d652871ebdc194735d7acda52f0a3eef7a46fb2f16bc4a0eeacd1542a3f63ad6d56e38a15484fa8' - - # ==> Controller configuration - # Configure the parent class to the devise controllers. - # config.parent_controller = 'DeviseController' - - # ==> Mailer Configuration - # Configure the e-mail address which will be shown in Devise::Mailer, - # note that it will be overwritten if you use your own mailer class - # with default "from" parameter. - config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' - - # Configure the class responsible to send e-mails. - # config.mailer = 'Devise::Mailer' - - # Configure the parent class responsible to send e-mails. - # config.parent_mailer = 'ActionMailer::Base' - - # ==> ORM configuration - # Load and configure the ORM. Supports :active_record (default) and - # :mongoid (bson_ext recommended) by default. Other ORMs may be - # available as additional gems. - require 'devise/orm/active_record' - - # ==> Configuration for any authentication mechanism - # Configure which keys are used when authenticating a user. The default is - # just :email. You can configure it to use [:username, :subdomain], so for - # authenticating a user, both parameters are required. Remember that those - # parameters are used only when authenticating and not when retrieving from - # session. If you need permissions, you should implement that in a before filter. - # You can also supply a hash where the value is a boolean determining whether - # or not authentication should be aborted when the value is not present. - config.authentication_keys = [ :username ] - - # Configure parameters from the request object used for authentication. Each entry - # given should be a request method and it will automatically be passed to the - # find_for_authentication method and considered in your model lookup. For instance, - # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. - # The same considerations mentioned for authentication_keys also apply to request_keys. - # config.request_keys = [] - - # Configure which authentication keys should be case-insensitive. - # These keys will be downcased upon creating or modifying a user and when used - # to authenticate or find a user. Default is :email. - config.case_insensitive_keys = [:email] - - # Configure which authentication keys should have whitespace stripped. - # These keys will have whitespace before and after removed upon creating or - # modifying a user and when used to authenticate or find a user. Default is :email. - config.strip_whitespace_keys = [:email] - - # Tell if authentication through request.params is enabled. True by default. - # It can be set to an array that will enable params authentication only for the - # given strategies, for example, `config.params_authenticatable = [:database]` will - # enable it only for database (email + password) authentication. - # config.params_authenticatable = true - - # Tell if authentication through HTTP Auth is enabled. False by default. - # It can be set to an array that will enable http authentication only for the - # given strategies, for example, `config.http_authenticatable = [:database]` will - # enable it only for database authentication. - # For API-only applications to support authentication "out-of-the-box", you will likely want to - # enable this with :database unless you are using a custom strategy. - # The supported strategies are: - # :database = Support basic authentication with authentication key + password - config.http_authenticatable = true - - # If 401 status code should be returned for AJAX requests. True by default. - # config.http_authenticatable_on_xhr = true - - # The realm used in Http Basic Authentication. 'Application' by default. - # config.http_authentication_realm = 'Application' - - # It will change confirmation, password recovery and other workflows - # to behave the same regardless if the e-mail provided was right or wrong. - # Does not affect registerable. - # config.paranoid = true - - # By default Devise will store the user in session. You can skip storage for - # particular strategies by setting this option. - # Notice that if you are skipping storage for all authentication paths, you - # may want to disable generating routes to Devise's sessions controller by - # passing skip: :sessions to `devise_for` in your config/routes.rb - config.skip_session_storage = [:http_auth] - - # By default, Devise cleans up the CSRF token on authentication to - # avoid CSRF token fixation attacks. This means that, when using AJAX - # requests for sign in and sign up, you need to get a new CSRF token - # from the server. You can disable this option at your own risk. - # config.clean_up_csrf_token_on_authentication = true - - # When false, Devise will not attempt to reload routes on eager load. - # This can reduce the time taken to boot the app but if your application - # requires the Devise mappings to be loaded during boot time the application - # won't boot properly. - # config.reload_routes = true - - # ==> Configuration for :database_authenticatable - # For bcrypt, this is the cost for hashing the password and defaults to 12. If - # using other algorithms, it sets how many times you want the password to be hashed. - # The number of stretches used for generating the hashed password are stored - # with the hashed password. This allows you to change the stretches without - # invalidating existing passwords. - # - # Limiting the stretches to just one in testing will increase the performance of - # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use - # a value less than 10 in other environments. Note that, for bcrypt (the default - # algorithm), the cost increases exponentially with the number of stretches (e.g. - # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). - config.stretches = Rails.env.test? ? 1 : 12 - - # Set up a pepper to generate the hashed password. - # config.pepper = '8b94639bc3aa104aa9b17554d6209cdc5bbbd767a3296f3f6600220cda59ddae62ddc13c37250d3602924f4e4d9c0e24788e318eba5c60dff77e478139388460' - - # Send a notification to the original email when the user's email is changed. - # config.send_email_changed_notification = false - - # Send a notification email when the user's password is changed. - # config.send_password_change_notification = false - - # ==> Configuration for :confirmable - # A period that the user is allowed to access the website even without - # confirming their account. For instance, if set to 2.days, the user will be - # able to access the website for two days without confirming their account, - # access will be blocked just in the third day. - # You can also set it to nil, which will allow the user to access the website - # without confirming their account. - # Default is 0.days, meaning the user cannot access the website without - # confirming their account. - # config.allow_unconfirmed_access_for = 2.days - - # A period that the user is allowed to confirm their account before their - # token becomes invalid. For example, if set to 3.days, the user can confirm - # their account within 3 days after the mail was sent, but on the fourth day - # their account can't be confirmed with the token any more. - # Default is nil, meaning there is no restriction on how long a user can take - # before confirming their account. - # config.confirm_within = 3.days - - # If true, requires any email changes to be confirmed (exactly the same way as - # initial account confirmation) to be applied. Requires additional unconfirmed_email - # db field (see migrations). Until confirmed, new email is stored in - # unconfirmed_email column, and copied to email column on successful confirmation. - config.reconfirmable = true - - # Defines which key will be used when confirming an account - # config.confirmation_keys = [:email] - - # ==> Configuration for :rememberable - # The time the user will be remembered without asking for credentials again. - # config.remember_for = 2.weeks - - # Invalidates all the remember me tokens when the user signs out. - config.expire_all_remember_me_on_sign_out = true - - # If true, extends the user's remember period when remembered via cookie. - # config.extend_remember_period = false - - # Options to be passed to the created cookie. For instance, you can set - # secure: true in order to force SSL only cookies. - # config.rememberable_options = {} - - # ==> Configuration for :validatable - # Range for password length. - config.password_length = 4..128 - - # Email regex used to validate email formats. It simply asserts that - # one (and only one) @ exists in the given string. This is mainly - # to give user feedback and not to assert the e-mail validity. - config.email_regexp = /\A[^@\s]+@[^@\s]+\z/ - - # ==> Configuration for :timeoutable - # The time you want to timeout the user session without activity. After this - # time the user will be asked for credentials again. Default is 30 minutes. - # config.timeout_in = 30.minutes - - # ==> Configuration for :lockable - # Defines which strategy will be used to lock an account. - # :failed_attempts = Locks an account after a number of failed attempts to sign in. - # :none = No lock strategy. You should handle locking by yourself. - # config.lock_strategy = :failed_attempts - - # Defines which key will be used when locking and unlocking an account - # config.unlock_keys = [:email] - - # Defines which strategy will be used to unlock an account. - # :email = Sends an unlock link to the user email - # :time = Re-enables login after a certain amount of time (see :unlock_in below) - # :both = Enables both strategies - # :none = No unlock strategy. You should handle unlocking by yourself. - # config.unlock_strategy = :both - - # Number of authentication tries before locking an account if lock_strategy - # is failed attempts. - # config.maximum_attempts = 20 - - # Time interval to unlock the account if :time is enabled as unlock_strategy. - # config.unlock_in = 1.hour - - # Warn on the last attempt before the account is locked. - # config.last_attempt_warning = true - - # ==> Configuration for :recoverable - # - # Defines which key will be used when recovering the password for an account - # config.reset_password_keys = [:email] - - # Time interval you can reset your password with a reset password key. - # Don't put a too small interval or your users won't have the time to - # change their passwords. - config.reset_password_within = 6.hours - - # When set to false, does not sign a user in automatically after their password is - # reset. Defaults to true, so a user is signed in automatically after a reset. - # config.sign_in_after_reset_password = true - - # ==> Configuration for :encryptable - # Allow you to use another hashing or encryption algorithm besides bcrypt (default). - # You can use :sha1, :sha512 or algorithms from others authentication tools as - # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20 - # for default behavior) and :restful_authentication_sha1 (then you should set - # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper). - # - # Require the `devise-encryptable` gem when using anything other than bcrypt - # config.encryptor = :sha512 - - # ==> Scopes configuration - # Turn scoped views on. Before rendering "sessions/new", it will first check for - # "users/sessions/new". It's turned off by default because it's slower if you - # are using only default views. - # config.scoped_views = false - - # Configure the default scope given to Warden. By default it's the first - # devise role declared in your routes (usually :user). - # config.default_scope = :user - - # Set this configuration to false if you want /users/sign_out to sign out - # only the current scope. By default, Devise signs out all scopes. - # config.sign_out_all_scopes = true - - # ==> Navigation configuration - # Lists the formats that should be treated as navigational. Formats like - # :html should redirect to the sign in page when the user does not have - # access, but formats like :xml or :json, should return 401. - # - # If you have any extra navigational formats, like :iphone or :mobile, you - # should add them to the navigational formats lists. - # - # The "*/*" below is required to match Internet Explorer requests. - # config.navigational_formats = ['*/*', :html, :turbo_stream] - - # The default HTTP method used to sign out a resource. Default is :delete. - config.sign_out_via = :delete - - # ==> OmniAuth - # Add a new OmniAuth provider. Check the wiki for more information on setting - # up on your models and hooks. - # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' - - # ==> Warden configuration - # If you want to use other strategies, that are not supported by Devise, or - # change the failure app, you can configure them inside the config.warden block. - # - # config.warden do |manager| - # manager.intercept_401 = false - # manager.default_strategies(scope: :user).unshift :some_external_strategy - # end - - # ==> Mountable engine configurations - # When using Devise inside an engine, let's call it `MyEngine`, and this engine - # is mountable, there are some extra configurations to be taken into account. - # The following options are available, assuming the engine is mounted as: - # - # mount MyEngine, at: '/my_engine' - # - # The router that invoked `devise_for`, in the example above, would be: - # config.router_name = :my_engine - # - # When using OmniAuth, Devise cannot automatically set OmniAuth path, - # so you need to do it manually. For the users scope, it would be: - # config.omniauth_path_prefix = '/my_engine/users/auth' - - # ==> Configuration for :registerable - - # When set to false, does not sign a user in automatically after their password is - # changed. Defaults to true, so a user is signed in automatically after changing a password. - # config.sign_in_after_change_password = true -end diff --git a/utils/build/docker/ruby/rails41/config/initializers/filter_parameter_logging.rb b/utils/build/docker/ruby/rails41/config/initializers/filter_parameter_logging.rb deleted file mode 100644 index 4a994e1e7bb..00000000000 --- a/utils/build/docker/ruby/rails41/config/initializers/filter_parameter_logging.rb +++ /dev/null @@ -1,4 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Configure sensitive parameters which will be filtered from the log file. -Rails.application.config.filter_parameters += [:password] diff --git a/utils/build/docker/ruby/rails41/config/initializers/inflections.rb b/utils/build/docker/ruby/rails41/config/initializers/inflections.rb deleted file mode 100644 index ac033bf9dc8..00000000000 --- a/utils/build/docker/ruby/rails41/config/initializers/inflections.rb +++ /dev/null @@ -1,16 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new inflection rules using the following format. Inflections -# are locale specific, and you may define rules for as many different -# locales as you wish. All of these examples are active by default: -# ActiveSupport::Inflector.inflections(:en) do |inflect| -# inflect.plural /^(ox)$/i, '\1en' -# inflect.singular /^(ox)en/i, '\1' -# inflect.irregular 'person', 'people' -# inflect.uncountable %w( fish sheep ) -# end - -# These inflection rules are supported but not enabled by default: -# ActiveSupport::Inflector.inflections(:en) do |inflect| -# inflect.acronym 'RESTful' -# end diff --git a/utils/build/docker/ruby/rails41/config/initializers/mime_types.rb b/utils/build/docker/ruby/rails41/config/initializers/mime_types.rb deleted file mode 100644 index dc1899682b0..00000000000 --- a/utils/build/docker/ruby/rails41/config/initializers/mime_types.rb +++ /dev/null @@ -1,4 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new mime types for use in respond_to blocks: -# Mime::Type.register "text/richtext", :rtf diff --git a/utils/build/docker/ruby/rails41/config/initializers/session_store.rb b/utils/build/docker/ruby/rails41/config/initializers/session_store.rb deleted file mode 100644 index 080bcea9a69..00000000000 --- a/utils/build/docker/ruby/rails41/config/initializers/session_store.rb +++ /dev/null @@ -1,3 +0,0 @@ -# Be sure to restart your server when you modify this file. - -Rails.application.config.session_store :cookie_store, key: '_rails41_session' diff --git a/utils/build/docker/ruby/rails41/config/initializers/wrap_parameters.rb b/utils/build/docker/ruby/rails41/config/initializers/wrap_parameters.rb deleted file mode 100644 index 33725e95fd2..00000000000 --- a/utils/build/docker/ruby/rails41/config/initializers/wrap_parameters.rb +++ /dev/null @@ -1,14 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# This file contains settings for ActionController::ParamsWrapper which -# is enabled by default. - -# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. -ActiveSupport.on_load(:action_controller) do - wrap_parameters format: [:json] if respond_to?(:wrap_parameters) -end - -# To enable root element in JSON for ActiveRecord objects. -# ActiveSupport.on_load(:active_record) do -# self.include_root_in_json = true -# end diff --git a/utils/build/docker/ruby/rails41/config/locales/en.yml b/utils/build/docker/ruby/rails41/config/locales/en.yml deleted file mode 100644 index 0653957166e..00000000000 --- a/utils/build/docker/ruby/rails41/config/locales/en.yml +++ /dev/null @@ -1,23 +0,0 @@ -# Files in the config/locales directory are used for internationalization -# and are automatically loaded by Rails. If you want to use locales other -# than English, add the necessary files in this directory. -# -# To use the locales, use `I18n.t`: -# -# I18n.t 'hello' -# -# In views, this is aliased to just `t`: -# -# <%= t('hello') %> -# -# To use a different locale, set it with `I18n.locale`: -# -# I18n.locale = :es -# -# This would use the information in config/locales/es.yml. -# -# To learn more, please read the Rails Internationalization guide -# available at http://guides.rubyonrails.org/i18n.html. - -en: - hello: "Hello world" diff --git a/utils/build/docker/ruby/rails41/config/routes.rb b/utils/build/docker/ruby/rails41/config/routes.rb deleted file mode 100644 index 007057c8690..00000000000 --- a/utils/build/docker/ruby/rails41/config/routes.rb +++ /dev/null @@ -1,35 +0,0 @@ -Rails.application.routes.draw do - get '/' => 'system_test#root' - post '/' => 'system_test#root' - - get '/waf' => 'system_test#waf' - post '/waf' => 'system_test#waf' - get '/waf/*other' => 'system_test#waf' - post '/waf/*other' => 'system_test#waf' - - get '/params/:value' => 'system_test#handle_path_params' - get '/spans' => 'system_test#generate_spans' - get '/status' => 'system_test#status' - get '/make_distant_call' => 'system_test#make_distant_call' - - get '/headers' => 'system_test#test_headers' - get '/identify' => 'system_test#identify' - - get 'user_login_success_event' => 'system_test#user_login_success_event' - get 'user_login_failure_event' => 'system_test#user_login_failure_event' - get 'custom_event' => 'system_test#custom_event' - - %i(get post).each do |request_method| - send(request_method, '/tag_value/:tag_value/:status_code' => 'system_test#tag_value') - end - match '/tag_value/:tag_value/:status_code' => 'system_test#tag_value', via: :options - get '/users' => 'system_test#users' - - devise_for :users - %i(get post).each do |request_method| - # We have to provide format: false to make sure the Test_DiscoveryScan test do not break - # https://github.com/DataDog/system-tests/blob/6873c9577ddc15693a98f9683075a1b9d4e587f0/tests/appsec/waf/test_rules.py#L374 - # The test hits '/login.pwd' and expects a 404. By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists - send(request_method, '/login' => 'system_test#login', format: false) - end -end diff --git a/utils/build/docker/ruby/rails41/config/secrets.yml b/utils/build/docker/ruby/rails41/config/secrets.yml deleted file mode 100644 index 8a844f7f24e..00000000000 --- a/utils/build/docker/ruby/rails41/config/secrets.yml +++ /dev/null @@ -1,22 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Your secret key is used for verifying the integrity of signed cookies. -# If you change this key, all old signed cookies will become invalid! - -# Make sure the secret is at least 30 characters and all random, -# no regular words or you'll be exposed to dictionary attacks. -# You can use `rake secret` to generate a secure secret key. - -# Make sure the secrets in this file are kept private -# if you're sharing your code publicly. - -development: - secret_key_base: 11b50ac0f05654df6773089ba928a185ca9f7c2f24a9ac493c52703dd602036f4aeb1764ee6392f08a06e04d5ed5a3f48656e3de326805be91459f8e69fb96c0 - -test: - secret_key_base: e4d6dd9246d5d2fe497f8985074ca9bc698f6d889b8d1e04eb46442d439ff85a8ce3e5c8b776ed998d7be5d705a1069ec6a5999da0d5ca52f3c54f18cc2b7223 - -# Do not keep production secrets in the repository, -# instead read values from the environment. -production: - secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> diff --git a/utils/build/docker/ruby/rails41/db/migrate/20230621141816_devise_create_users.rb b/utils/build/docker/ruby/rails41/db/migrate/20230621141816_devise_create_users.rb deleted file mode 100644 index 992282a81cc..00000000000 --- a/utils/build/docker/ruby/rails41/db/migrate/20230621141816_devise_create_users.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -class DeviseCreateUsers < ActiveRecord::Migration - def change - create_table :users, id: :string do |t| - ## Database authenticatable - t.string :username, null: false, default: "" - t.string :email, null: false, default: "" - t.string :encrypted_password, null: false, default: "" - - ## Recoverable - t.string :reset_password_token - t.datetime :reset_password_sent_at - - ## Rememberable - t.datetime :remember_created_at - - ## Trackable - # t.integer :sign_in_count, default: 0, null: false - # t.datetime :current_sign_in_at - # t.datetime :last_sign_in_at - # t.string :current_sign_in_ip - # t.string :last_sign_in_ip - - ## Confirmable - # t.string :confirmation_token - # t.datetime :confirmed_at - # t.datetime :confirmation_sent_at - # t.string :unconfirmed_email # Only if using reconfirmable - - ## Lockable - # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts - # t.string :unlock_token # Only if unlock strategy is :email or :both - # t.datetime :locked_at - - - t.timestamps null: false - end - - add_index :users, :email, unique: true - add_index :users, :reset_password_token, unique: true - # add_index :users, :confirmation_token, unique: true - # add_index :users, :unlock_token, unique: true - end -end diff --git a/utils/build/docker/ruby/rails41/public/404.html b/utils/build/docker/ruby/rails41/public/404.html deleted file mode 100644 index b612547fc21..00000000000 --- a/utils/build/docker/ruby/rails41/public/404.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - The page you were looking for doesn't exist (404) - - - - - - -
-
-

The page you were looking for doesn't exist.

-

You may have mistyped the address or the page may have moved.

-
-

If you are the application owner check the logs for more information.

-
- - diff --git a/utils/build/docker/ruby/rails41/public/422.html b/utils/build/docker/ruby/rails41/public/422.html deleted file mode 100644 index a21f82b3bdb..00000000000 --- a/utils/build/docker/ruby/rails41/public/422.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - The change you wanted was rejected (422) - - - - - - -
-
-

The change you wanted was rejected.

-

Maybe you tried to change something you didn't have access to.

-
-

If you are the application owner check the logs for more information.

-
- - diff --git a/utils/build/docker/ruby/rails41/public/500.html b/utils/build/docker/ruby/rails41/public/500.html deleted file mode 100644 index 061abc587dc..00000000000 --- a/utils/build/docker/ruby/rails41/public/500.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - We're sorry, but something went wrong (500) - - - - - - -
-
-

We're sorry, but something went wrong.

-
-

If you are the application owner check the logs for more information.

-
- - diff --git a/utils/build/docker/ruby/rails41/public/robots.txt b/utils/build/docker/ruby/rails41/public/robots.txt deleted file mode 100644 index 3c9c7c01f30..00000000000 --- a/utils/build/docker/ruby/rails41/public/robots.txt +++ /dev/null @@ -1,5 +0,0 @@ -# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file -# -# To ban all spiders from the entire site uncomment the next two lines: -# User-agent: * -# Disallow: / diff --git a/utils/build/docker/ruby/rails41/test/test_helper.rb b/utils/build/docker/ruby/rails41/test/test_helper.rb deleted file mode 100644 index 92e39b2d78c..00000000000 --- a/utils/build/docker/ruby/rails41/test/test_helper.rb +++ /dev/null @@ -1,10 +0,0 @@ -ENV['RAILS_ENV'] ||= 'test' -require File.expand_path('../../config/environment', __FILE__) -require 'rails/test_help' - -class ActiveSupport::TestCase - # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. - fixtures :all - - # Add more helper methods to be used by all tests here... -end diff --git a/utils/build/docker/ruby/rails42.Dockerfile b/utils/build/docker/ruby/rails42.Dockerfile index 18bc7ac1b71..84b98148fb5 100644 --- a/utils/build/docker/ruby/rails42.Dockerfile +++ b/utils/build/docker/ruby/rails42.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:2.3.8-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:2.5 RUN curl -O https://rubygems.org/downloads/libv8-node-15.14.0.1-$(arch)-linux.gem && gem install libv8-node-15.14.0.1-$(arch)-linux.gem && rm libv8-node-15.14.0.1-$(arch)-linux.gem diff --git a/utils/build/docker/ruby/rails42/Gemfile b/utils/build/docker/ruby/rails42/Gemfile index 267a9be209e..a37da95630b 100644 --- a/utils/build/docker/ruby/rails42/Gemfile +++ b/utils/build/docker/ruby/rails42/Gemfile @@ -20,8 +20,6 @@ gem 'jquery-rails' gem 'turbolinks' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.0' -# bundle exec rake doc:rails generates the API under doc/api. -gem 'sdoc', '~> 0.4.0', group: :doc # Use ActiveModel has_secure_password # gem 'bcrypt', '~> 3.1.7' diff --git a/utils/build/docker/ruby/rails42/Gemfile.lock b/utils/build/docker/ruby/rails42/Gemfile.lock index 65ae1dbf8fd..a6d8f677f44 100644 --- a/utils/build/docker/ruby/rails42/Gemfile.lock +++ b/utils/build/docker/ruby/rails42/Gemfile.lock @@ -75,7 +75,6 @@ GEM rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - json (1.8.6) libddwaf (1.0.14.2.0.beta1) ffi (~> 1.0) libddwaf (1.0.14.2.0.beta1-aarch64-linux) @@ -139,7 +138,6 @@ GEM rb-fsevent (0.11.0) rb-inotify (0.10.1) ffi (~> 1.0) - rdoc (4.3.0) responders (2.4.1) actionpack (>= 4.2.0, < 6.0) railties (>= 4.2.0, < 6.0) @@ -154,9 +152,6 @@ GEM sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) - sdoc (0.4.2) - json (~> 1.7, >= 1.7.7) - rdoc (~> 4.0) sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -201,7 +196,6 @@ DEPENDENCIES puma (= 5.0.2) rails (= 4.2.11.3) sass-rails (~> 5.0) - sdoc (~> 0.4.0) sqlite3 (< 1.4) turbolinks uglifier (>= 1.3.0) diff --git a/utils/build/docker/ruby/rails42/app/controllers/system_test_controller.rb b/utils/build/docker/ruby/rails42/app/controllers/system_test_controller.rb index a911b62b67a..cc1ed02b06d 100644 --- a/utils/build/docker/ruby/rails42/app/controllers/system_test_controller.rb +++ b/utils/build/docker/ruby/rails42/app/controllers/system_test_controller.rb @@ -1,3 +1,5 @@ +require 'json' + require 'datadog/kit/appsec/events' class SystemTestController < ApplicationController @@ -7,6 +9,19 @@ def root render plain: 'Hello, world!' end + def healthcheck + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + render json: { + status: 'ok', + library: { + language: 'ruby', + version: version + } + } + end + def waf render plain: 'Hello, world!' end @@ -165,4 +180,28 @@ def login render plain: 'Hello, world!' end + + def request_downstream + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + render json: ext_response.body, content_type: 'application/json' + end + + def return_headers + request_headers = request.headers.each.to_h.select do |k, _v| + k.start_with?('HTTP_') || k == 'CONTENT_TYPE' || k == 'CONTENT_LENGTH' + end + request_headers = request_headers.transform_keys do |k| + k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') + end + render json: JSON.generate(request_headers), content_type: 'application/json' + end end diff --git a/utils/build/docker/ruby/rails42/config/routes.rb b/utils/build/docker/ruby/rails42/config/routes.rb index bf0c162c093..b4300f1e965 100644 --- a/utils/build/docker/ruby/rails42/config/routes.rb +++ b/utils/build/docker/ruby/rails42/config/routes.rb @@ -2,6 +2,8 @@ get '/' => 'system_test#root' post '/' => 'system_test#root' + get '/healthcheck' => 'system_test#healthcheck' + get '/waf' => 'system_test#waf' post '/waf' => 'system_test#waf' get '/waf/*other' => 'system_test#waf' @@ -13,22 +15,26 @@ get '/make_distant_call' => 'system_test#make_distant_call' get '/headers' => 'system_test#test_headers' - get '/identify' => 'system_test#identify' + get '/identify' => 'system_test#identify' get 'user_login_success_event' => 'system_test#user_login_success_event' get 'user_login_failure_event' => 'system_test#user_login_failure_event' get 'custom_event' => 'system_test#custom_event' - %i(get post).each do |request_method| + %i[get post].each do |request_method| send(request_method, '/tag_value/:tag_value/:status_code' => 'system_test#tag_value') end match '/tag_value/:tag_value/:status_code' => 'system_test#tag_value', via: :options get '/users' => 'system_test#users' devise_for :users - %i(get post).each do |request_method| + %i[get post].each do |request_method| # We have to provide format: false to make sure the Test_DiscoveryScan test do not break # https://github.com/DataDog/system-tests/blob/6873c9577ddc15693a98f9683075a1b9d4e587f0/tests/appsec/waf/test_rules.py#L374 - # The test hits '/login.pwd' and expects a 404. By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists + # The test hits '/login.pwd' and expects a 404. + # By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists send(request_method, '/login' => 'system_test#login', format: false) end + + get '/requestdownstream' => 'system_test#request_downstream' + get '/returnheaders' => 'system_test#return_headers' end diff --git a/utils/build/docker/ruby/rails50.Dockerfile b/utils/build/docker/ruby/rails50.Dockerfile index 234cc99a21c..1a031c22093 100644 --- a/utils/build/docker/ruby/rails50.Dockerfile +++ b/utils/build/docker/ruby/rails50.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:2.5.9-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:2.5 RUN curl -O https://rubygems.org/downloads/libv8-node-15.14.0.1-$(arch)-linux.gem && gem install libv8-node-15.14.0.1-$(arch)-linux.gem && rm libv8-node-15.14.0.1-$(arch)-linux.gem diff --git a/utils/build/docker/ruby/rails50/app/controllers/system_test_controller.rb b/utils/build/docker/ruby/rails50/app/controllers/system_test_controller.rb index 896935a498f..e040bde78bb 100644 --- a/utils/build/docker/ruby/rails50/app/controllers/system_test_controller.rb +++ b/utils/build/docker/ruby/rails50/app/controllers/system_test_controller.rb @@ -1,3 +1,5 @@ +require 'json' + require 'datadog/kit/appsec/events' class SystemTestController < ApplicationController @@ -7,6 +9,19 @@ def root render plain: 'Hello, world!' end + def healthcheck + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + render json: { + status: 'ok', + library: { + language: 'ruby', + version: version + } + } + end + def waf render plain: 'Hello, world!' end @@ -165,4 +180,28 @@ def login render plain: 'Hello, world!' end + + def request_downstream + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + render json: ext_response.body, content_type: 'application/json' + end + + def return_headers + request_headers = request.headers.each.to_h.select do |k, _v| + k.start_with?('HTTP_') || k == 'CONTENT_TYPE' || k == 'CONTENT_LENGTH' + end + request_headers = request_headers.transform_keys do |k| + k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') + end + render json: JSON.generate(request_headers), content_type: 'application/json' + end end diff --git a/utils/build/docker/ruby/rails50/config/routes.rb b/utils/build/docker/ruby/rails50/config/routes.rb index e9146665bb3..8301a3a1d1b 100644 --- a/utils/build/docker/ruby/rails50/config/routes.rb +++ b/utils/build/docker/ruby/rails50/config/routes.rb @@ -4,6 +4,8 @@ get '/' => 'system_test#root' post '/' => 'system_test#root' + get '/healthcheck' => 'system_test#healthcheck' + get '/waf' => 'system_test#waf' post '/waf' => 'system_test#waf' get '/waf/*other' => 'system_test#waf' @@ -15,23 +17,27 @@ get '/make_distant_call' => 'system_test#make_distant_call' get '/headers' => 'system_test#test_headers' - get '/identify' => 'system_test#identify' + get '/identify' => 'system_test#identify' get 'user_login_success_event' => 'system_test#user_login_success_event' get 'user_login_failure_event' => 'system_test#user_login_failure_event' get 'custom_event' => 'system_test#custom_event' - %i(get post).each do |request_method| + %i[get post].each do |request_method| send(request_method, '/tag_value/:tag_value/:status_code' => 'system_test#tag_value') end match '/tag_value/:tag_value/:status_code' => 'system_test#tag_value', via: :options get '/users' => 'system_test#users' devise_for :users - %i(get post).each do |request_method| + %i[get post].each do |request_method| # We have to provide format: false to make sure the Test_DiscoveryScan test do not break # https://github.com/DataDog/system-tests/blob/6873c9577ddc15693a98f9683075a1b9d4e587f0/tests/appsec/waf/test_rules.py#L374 - # The test hits '/login.pwd' and expects a 404. By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists + # The test hits '/login.pwd' and expects a 404. + # By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists send(request_method, '/login' => 'system_test#login', format: false) end + + get '/requestdownstream' => 'system_test#request_downstream' + get '/returnheaders' => 'system_test#return_headers' end diff --git a/utils/build/docker/ruby/rails51.Dockerfile b/utils/build/docker/ruby/rails51.Dockerfile index bfeff1af752..8e2c24477e4 100644 --- a/utils/build/docker/ruby/rails51.Dockerfile +++ b/utils/build/docker/ruby/rails51.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:2.6.7-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:2.6 RUN curl -O https://rubygems.org/downloads/libv8-node-16.10.0.0-$(arch)-linux.gem && gem install libv8-node-16.10.0.0-$(arch)-linux.gem && rm libv8-node-16.10.0.0-$(arch)-linux.gem && gem install mini_racer:'0.6.2' diff --git a/utils/build/docker/ruby/rails51/app/controllers/system_test_controller.rb b/utils/build/docker/ruby/rails51/app/controllers/system_test_controller.rb index c135958873c..da816589329 100644 --- a/utils/build/docker/ruby/rails51/app/controllers/system_test_controller.rb +++ b/utils/build/docker/ruby/rails51/app/controllers/system_test_controller.rb @@ -1,3 +1,5 @@ +require 'json' + require 'datadog/kit/appsec/events' class SystemTestController < ApplicationController @@ -7,6 +9,19 @@ def root render plain: 'Hello, world!' end + def healthcheck + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + render json: { + status: 'ok', + library: { + language: 'ruby', + version: version + } + } + end + def waf render plain: 'Hello, world!' end @@ -164,4 +179,28 @@ def login render plain: 'Hello, world!' end + + def request_downstream + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + render json: ext_response.body, content_type: 'application/json' + end + + def return_headers + request_headers = request.headers.each.to_h.select do |k, _v| + k.start_with?('HTTP_') || k == 'CONTENT_TYPE' || k == 'CONTENT_LENGTH' + end + request_headers = request_headers.transform_keys do |k| + k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') + end + render json: JSON.generate(request_headers), content_type: 'application/json' + end end diff --git a/utils/build/docker/ruby/rails51/config/routes.rb b/utils/build/docker/ruby/rails51/config/routes.rb index 0f0a6e4ebc0..8b769b09088 100644 --- a/utils/build/docker/ruby/rails51/config/routes.rb +++ b/utils/build/docker/ruby/rails51/config/routes.rb @@ -4,6 +4,8 @@ get '/' => 'system_test#root' post '/' => 'system_test#root' + get '/healthcheck' => 'system_test#healthcheck' + get '/waf' => 'system_test#waf' post '/waf' => 'system_test#waf' get '/waf/*other' => 'system_test#waf' @@ -15,23 +17,27 @@ get '/make_distant_call' => 'system_test#make_distant_call' get '/headers' => 'system_test#test_headers' - get '/identify' => 'system_test#identify' + get '/identify' => 'system_test#identify' get 'user_login_success_event' => 'system_test#user_login_success_event' get 'user_login_failure_event' => 'system_test#user_login_failure_event' get 'custom_event' => 'system_test#custom_event' - %i(get post).each do |request_method| + %i[get post].each do |request_method| send(request_method, '/tag_value/:tag_value/:status_code' => 'system_test#tag_value') end match '/tag_value/:tag_value/:status_code' => 'system_test#tag_value', via: :options get '/users' => 'system_test#users' devise_for :users - %i(get post).each do |request_method| + %i[get post].each do |request_method| # We have to provide format: false to make sure the Test_DiscoveryScan test do not break # https://github.com/DataDog/system-tests/blob/515310b5fb1fd0792fc283c9ee134ab3803d6e7c/tests/appsec/waf/test_rules.py#L374 - # The test hits '/login.pwd' and expects a 404. By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists + # The test hits '/login.pwd' and expects a 404. + # By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists send(request_method, '/login' => 'system_test#login', format: false) end + + get '/requestdownstream' => 'system_test#request_downstream' + get '/returnheaders' => 'system_test#return_headers' end diff --git a/utils/build/docker/ruby/rails52.Dockerfile b/utils/build/docker/ruby/rails52.Dockerfile index 850e7fdbbb3..a751f2abe86 100644 --- a/utils/build/docker/ruby/rails52.Dockerfile +++ b/utils/build/docker/ruby/rails52.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:2.7.6-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:2.7 RUN curl -O https://rubygems.org/downloads/libv8-node-16.10.0.0-$(arch)-linux.gem && gem install libv8-node-16.10.0.0-$(arch)-linux.gem && rm libv8-node-16.10.0.0-$(arch)-linux.gem && gem install mini_racer:'0.6.2' diff --git a/utils/build/docker/ruby/rails52/app/controllers/system_test_controller.rb b/utils/build/docker/ruby/rails52/app/controllers/system_test_controller.rb index 896935a498f..e040bde78bb 100644 --- a/utils/build/docker/ruby/rails52/app/controllers/system_test_controller.rb +++ b/utils/build/docker/ruby/rails52/app/controllers/system_test_controller.rb @@ -1,3 +1,5 @@ +require 'json' + require 'datadog/kit/appsec/events' class SystemTestController < ApplicationController @@ -7,6 +9,19 @@ def root render plain: 'Hello, world!' end + def healthcheck + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + render json: { + status: 'ok', + library: { + language: 'ruby', + version: version + } + } + end + def waf render plain: 'Hello, world!' end @@ -165,4 +180,28 @@ def login render plain: 'Hello, world!' end + + def request_downstream + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + render json: ext_response.body, content_type: 'application/json' + end + + def return_headers + request_headers = request.headers.each.to_h.select do |k, _v| + k.start_with?('HTTP_') || k == 'CONTENT_TYPE' || k == 'CONTENT_LENGTH' + end + request_headers = request_headers.transform_keys do |k| + k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') + end + render json: JSON.generate(request_headers), content_type: 'application/json' + end end diff --git a/utils/build/docker/ruby/rails52/config/routes.rb b/utils/build/docker/ruby/rails52/config/routes.rb index e9146665bb3..8b769b09088 100644 --- a/utils/build/docker/ruby/rails52/config/routes.rb +++ b/utils/build/docker/ruby/rails52/config/routes.rb @@ -4,6 +4,8 @@ get '/' => 'system_test#root' post '/' => 'system_test#root' + get '/healthcheck' => 'system_test#healthcheck' + get '/waf' => 'system_test#waf' post '/waf' => 'system_test#waf' get '/waf/*other' => 'system_test#waf' @@ -15,23 +17,27 @@ get '/make_distant_call' => 'system_test#make_distant_call' get '/headers' => 'system_test#test_headers' - get '/identify' => 'system_test#identify' + get '/identify' => 'system_test#identify' get 'user_login_success_event' => 'system_test#user_login_success_event' get 'user_login_failure_event' => 'system_test#user_login_failure_event' get 'custom_event' => 'system_test#custom_event' - %i(get post).each do |request_method| + %i[get post].each do |request_method| send(request_method, '/tag_value/:tag_value/:status_code' => 'system_test#tag_value') end match '/tag_value/:tag_value/:status_code' => 'system_test#tag_value', via: :options get '/users' => 'system_test#users' devise_for :users - %i(get post).each do |request_method| + %i[get post].each do |request_method| # We have to provide format: false to make sure the Test_DiscoveryScan test do not break - # https://github.com/DataDog/system-tests/blob/6873c9577ddc15693a98f9683075a1b9d4e587f0/tests/appsec/waf/test_rules.py#L374 - # The test hits '/login.pwd' and expects a 404. By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists + # https://github.com/DataDog/system-tests/blob/515310b5fb1fd0792fc283c9ee134ab3803d6e7c/tests/appsec/waf/test_rules.py#L374 + # The test hits '/login.pwd' and expects a 404. + # By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists send(request_method, '/login' => 'system_test#login', format: false) end + + get '/requestdownstream' => 'system_test#request_downstream' + get '/returnheaders' => 'system_test#return_headers' end diff --git a/utils/build/docker/ruby/rails60.Dockerfile b/utils/build/docker/ruby/rails60.Dockerfile index 335415dd939..bf06b72c6a4 100644 --- a/utils/build/docker/ruby/rails60.Dockerfile +++ b/utils/build/docker/ruby/rails60.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:2.7.6-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:2.7 RUN apt-get update && apt-get install -y nodejs npm RUN npm install -g yarn diff --git a/utils/build/docker/ruby/rails60/app/controllers/system_test_controller.rb b/utils/build/docker/ruby/rails60/app/controllers/system_test_controller.rb index ba858a3e5f1..9c7418e53ea 100644 --- a/utils/build/docker/ruby/rails60/app/controllers/system_test_controller.rb +++ b/utils/build/docker/ruby/rails60/app/controllers/system_test_controller.rb @@ -1,3 +1,5 @@ +require 'json' + require 'datadog/kit/appsec/events' class SystemTestController < ApplicationController @@ -7,6 +9,19 @@ def root render plain: 'Hello, world!' end + def healthcheck + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + render json: { + status: 'ok', + library: { + language: 'ruby', + version: version + } + } + end + def waf render plain: 'Hello, world!' end @@ -185,4 +200,28 @@ def login render plain: 'Hello, world!' end + + def request_downstream + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + render json: ext_response.body, content_type: 'application/json' + end + + def return_headers + request_headers = request.headers.each.to_h.select do |k, _v| + k.start_with?('HTTP_') || k == 'CONTENT_TYPE' || k == 'CONTENT_LENGTH' + end + request_headers = request_headers.transform_keys do |k| + k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') + end + render json: JSON.generate(request_headers), content_type: 'application/json' + end end diff --git a/utils/build/docker/ruby/rails60/config/routes.rb b/utils/build/docker/ruby/rails60/config/routes.rb index 995d0ff6191..8b769b09088 100644 --- a/utils/build/docker/ruby/rails60/config/routes.rb +++ b/utils/build/docker/ruby/rails60/config/routes.rb @@ -1,9 +1,11 @@ Rails.application.routes.draw do - # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html + # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html get '/' => 'system_test#root' post '/' => 'system_test#root' + get '/healthcheck' => 'system_test#healthcheck' + get '/waf' => 'system_test#waf' post '/waf' => 'system_test#waf' get '/waf/*other' => 'system_test#waf' @@ -15,23 +17,27 @@ get '/make_distant_call' => 'system_test#make_distant_call' get '/headers' => 'system_test#test_headers' - get '/identify' => 'system_test#identify' + get '/identify' => 'system_test#identify' get 'user_login_success_event' => 'system_test#user_login_success_event' get 'user_login_failure_event' => 'system_test#user_login_failure_event' get 'custom_event' => 'system_test#custom_event' - %i(get post).each do |request_method| + %i[get post].each do |request_method| send(request_method, '/tag_value/:tag_value/:status_code' => 'system_test#tag_value') end match '/tag_value/:tag_value/:status_code' => 'system_test#tag_value', via: :options get '/users' => 'system_test#users' devise_for :users - %i(get post).each do |request_method| + %i[get post].each do |request_method| # We have to provide format: false to make sure the Test_DiscoveryScan test do not break # https://github.com/DataDog/system-tests/blob/515310b5fb1fd0792fc283c9ee134ab3803d6e7c/tests/appsec/waf/test_rules.py#L374 - # The test hits '/login.pwd' and expects a 404. By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists + # The test hits '/login.pwd' and expects a 404. + # By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists send(request_method, '/login' => 'system_test#login', format: false) end + + get '/requestdownstream' => 'system_test#request_downstream' + get '/returnheaders' => 'system_test#return_headers' end diff --git a/utils/build/docker/ruby/rails61.Dockerfile b/utils/build/docker/ruby/rails61.Dockerfile index 103a838ddf2..8caeb37efa9 100644 --- a/utils/build/docker/ruby/rails61.Dockerfile +++ b/utils/build/docker/ruby/rails61.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:3.0.3-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:3.0 RUN apt-get update && apt-get install -y nodejs npm RUN npm install -g yarn diff --git a/utils/build/docker/ruby/rails61/app/controllers/system_test_controller.rb b/utils/build/docker/ruby/rails61/app/controllers/system_test_controller.rb index 896935a498f..e040bde78bb 100644 --- a/utils/build/docker/ruby/rails61/app/controllers/system_test_controller.rb +++ b/utils/build/docker/ruby/rails61/app/controllers/system_test_controller.rb @@ -1,3 +1,5 @@ +require 'json' + require 'datadog/kit/appsec/events' class SystemTestController < ApplicationController @@ -7,6 +9,19 @@ def root render plain: 'Hello, world!' end + def healthcheck + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + render json: { + status: 'ok', + library: { + language: 'ruby', + version: version + } + } + end + def waf render plain: 'Hello, world!' end @@ -165,4 +180,28 @@ def login render plain: 'Hello, world!' end + + def request_downstream + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + render json: ext_response.body, content_type: 'application/json' + end + + def return_headers + request_headers = request.headers.each.to_h.select do |k, _v| + k.start_with?('HTTP_') || k == 'CONTENT_TYPE' || k == 'CONTENT_LENGTH' + end + request_headers = request_headers.transform_keys do |k| + k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') + end + render json: JSON.generate(request_headers), content_type: 'application/json' + end end diff --git a/utils/build/docker/ruby/rails61/config/routes.rb b/utils/build/docker/ruby/rails61/config/routes.rb index 995d0ff6191..8b769b09088 100644 --- a/utils/build/docker/ruby/rails61/config/routes.rb +++ b/utils/build/docker/ruby/rails61/config/routes.rb @@ -1,9 +1,11 @@ Rails.application.routes.draw do - # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html + # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html get '/' => 'system_test#root' post '/' => 'system_test#root' + get '/healthcheck' => 'system_test#healthcheck' + get '/waf' => 'system_test#waf' post '/waf' => 'system_test#waf' get '/waf/*other' => 'system_test#waf' @@ -15,23 +17,27 @@ get '/make_distant_call' => 'system_test#make_distant_call' get '/headers' => 'system_test#test_headers' - get '/identify' => 'system_test#identify' + get '/identify' => 'system_test#identify' get 'user_login_success_event' => 'system_test#user_login_success_event' get 'user_login_failure_event' => 'system_test#user_login_failure_event' get 'custom_event' => 'system_test#custom_event' - %i(get post).each do |request_method| + %i[get post].each do |request_method| send(request_method, '/tag_value/:tag_value/:status_code' => 'system_test#tag_value') end match '/tag_value/:tag_value/:status_code' => 'system_test#tag_value', via: :options get '/users' => 'system_test#users' devise_for :users - %i(get post).each do |request_method| + %i[get post].each do |request_method| # We have to provide format: false to make sure the Test_DiscoveryScan test do not break # https://github.com/DataDog/system-tests/blob/515310b5fb1fd0792fc283c9ee134ab3803d6e7c/tests/appsec/waf/test_rules.py#L374 - # The test hits '/login.pwd' and expects a 404. By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists + # The test hits '/login.pwd' and expects a 404. + # By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists send(request_method, '/login' => 'system_test#login', format: false) end + + get '/requestdownstream' => 'system_test#request_downstream' + get '/returnheaders' => 'system_test#return_headers' end diff --git a/utils/build/docker/ruby/rails70.Dockerfile b/utils/build/docker/ruby/rails70.Dockerfile index 6f5b436f5be..b60a642e74f 100644 --- a/utils/build/docker/ruby/rails70.Dockerfile +++ b/utils/build/docker/ruby/rails70.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:3.1.1-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:3.1 RUN apt-get update && apt-get install -y nodejs npm diff --git a/utils/build/docker/ruby/rails70/app/controllers/debugger_controller.rb b/utils/build/docker/ruby/rails70/app/controllers/debugger_controller.rb new file mode 100644 index 00000000000..9e5120d79c0 --- /dev/null +++ b/utils/build/docker/ruby/rails70/app/controllers/debugger_controller.rb @@ -0,0 +1,54 @@ +# Padding +# Padding +# Padding +# Padding + +class DebuggerController < ActionController::Base + def init + # This method does nothing. + # When the endpoint corresponding to it is invoked however, + # the middleware installed by dd-trace-rb initializes remote configuration. + render inline: 'debugger init' + end + + # Padding + # Padding + # Padding + # Padding + + def log_probe + render inline: 'Log probe' # This needs to be line 20 + end + + # Padding + # Padding + # Padding + # Padding + + def pii + pii = Pii.new + customPii = CustomPii.new + value = pii.test_value + custom_value = customPii.test_value + render inline: "PII #{value}. CustomPII #{custom_value}" # must be line 33 + end + + # Padding + # Padding + # Padding + # Padding + # Padding + # Padding + # Padding + # Padding + # Padding + # Padding + # Padding + # Padding + # Padding + + def mix_probe + value = params[:string_arg].length * Integer(params[:int_arg]) + render inline: "Mixed result #{value}" # must be line 52 + end +end diff --git a/utils/build/docker/ruby/rails70/app/controllers/system_test_controller.rb b/utils/build/docker/ruby/rails70/app/controllers/system_test_controller.rb index 1da71d87b31..53ec7001e5f 100644 --- a/utils/build/docker/ruby/rails70/app/controllers/system_test_controller.rb +++ b/utils/build/docker/ruby/rails70/app/controllers/system_test_controller.rb @@ -1,3 +1,5 @@ +require 'json' + require 'datadog/kit/appsec/events' require 'kafka' @@ -8,6 +10,19 @@ def root render plain: 'Hello, world!' end + def healthcheck + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + render json: { + status: 'ok', + library: { + language: 'ruby', + version: version + } + } + end + def waf render plain: 'Hello, world!' end @@ -172,45 +187,67 @@ def login def kafka_produce - kafka_client = Kafka.new(["kafka:9092"], client_id: "system-tests-client-producer") - topic = request.params["topic"] - stop = false - while stop == false - begin - Datadog::Tracing.trace('kafka_produce') do |span| - kafka_client.deliver_message("Hello, world!", topic: topic) - # This has to be done manually for now, because ruby does not add the topic - # to the span at all - span.set_tag("span.kind", "producer") - span.set_tag("kafka.topic", topic) - stop = true - end - rescue Kafka::LeaderNotAvailable - end + kafka = Kafka.new( + seed_brokers: ["kafka:9092"], + client_id: "system-tests-client-producer", + ) + producer = kafka.producer + topic = request.params["topic"] || "DistributedTracing" + begin + producer.produce( + "Hello, world!", + topic: topic, + ) + producer.deliver_messages + producer.shutdown + rescue Exception => e + puts "An error has occurred while consuming messages from Kafka: #{e}" end - render plain: "Done" end def kafka_consume - kafka_client = Kafka.new(["kafka:9092"], client_id: "system-tests-client-consumer") - topic = request.params["topic"] - consumer = kafka_client.consumer(group_id: "system-tests-group") - consumer.subscribe(topic) + kafka = Kafka.new( + seed_brokers: ["kafka:9092"], + client_id: "system-tests-client-consumer", + socket_timeout: 20, + ) + topic = request.params["topic"] || "DistributedTracing" begin - consumer.each_message do |message| + kafka.each_message(topic: topic) do |message| if not message.nil? + puts "Received message: #{message.value}" break end end rescue Exception => e puts "An error has occurred while consuming messages from Kafka: #{e}" - ensure - consumer.stop end - render plain: "Done" end + def request_downstream + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + render json: ext_response.body, content_type: 'application/json' + end + + def return_headers + request_headers = request.headers.each.to_h.select do |k, _v| + k.start_with?('HTTP_') || k == 'CONTENT_TYPE' || k == 'CONTENT_LENGTH' + end + request_headers = request_headers.transform_keys do |k| + k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') + end + render json: JSON.generate(request_headers), content_type: 'application/json' + end end diff --git a/utils/build/docker/ruby/rails70/app/models/base_pii.rb b/utils/build/docker/ruby/rails70/app/models/base_pii.rb new file mode 100644 index 00000000000..eedf66c48b9 --- /dev/null +++ b/utils/build/docker/ruby/rails70/app/models/base_pii.rb @@ -0,0 +1,7 @@ +class BasePii + def initialize + @test_value = 'should be redacted' + end + + attr_reader :test_value +end diff --git a/utils/build/docker/ruby/rails70/app/models/custom_pii.rb b/utils/build/docker/ruby/rails70/app/models/custom_pii.rb new file mode 100644 index 00000000000..234112fdc83 --- /dev/null +++ b/utils/build/docker/ruby/rails70/app/models/custom_pii.rb @@ -0,0 +1,5 @@ +class CustomPii < BasePii + def initialize + @custom_key = 'should be redacted' + end +end diff --git a/utils/build/docker/ruby/rails70/app/models/pii.rb b/utils/build/docker/ruby/rails70/app/models/pii.rb new file mode 100644 index 00000000000..fc303a2c0b9 --- /dev/null +++ b/utils/build/docker/ruby/rails70/app/models/pii.rb @@ -0,0 +1,109 @@ + +# Copied from test_debugger_pii.py + +REDACTED_KEYS = [ + "_2fa", + "accesstoken", + "access_token", + "Access_Token", + "accessToken", + "AccessToken", + "ACCESSTOKEN", + "aiohttpsession", + "apikey", + "apisecret", + "apisignature", + "applicationkey", + "auth", + "authorization", + "authtoken", + "ccnumber", + "certificatepin", + "cipher", + "clientid", + "clientsecret", + "connectionstring", + "connectsid", + "cookie", + "credentials", + "creditcard", + "csrf", + "csrftoken", + "cvv", + "databaseurl", + "dburl", + "encryptionkey", + "encryptionkeyid", + "env", + "geolocation", + "gpgkey", + "ipaddress", + "jti", + "jwt", + "licensekey", + "masterkey", + "mysqlpwd", + "nonce", + "oauth", + "oauthtoken", + "otp", + "passhash", + "passwd", + "password", + "passwordb", + "pemfile", + "pgpkey", + "phpsessid", + "pin", + "pincode", + "pkcs8", + "privatekey", + "publickey", + "pwd", + "recaptchakey", + "refreshtoken", + "routingnumber", + "salt", + "secret", + "secretkey", + "secrettoken", + "securityanswer", + "securitycode", + "securityquestion", + "serviceaccountcredentials", + "session", + "sessionid", + "sessionkey", + "setcookie", + "signature", + "signaturekey", + "sshkey", + "ssn", + "symfony", + "token", + "transactionid", + "twiliotoken", + "usersession", + "voterid", + "xapikey", + "xauthtoken", + "xcsrftoken", + "xforwardedfor", + "xrealip", + "xsrf", + "xsrftoken", + "customidentifier1", + "customidentifier2", +] + +REDACTED_TYPES = ["customPii"] + +VALUE = "SHOULD_BE_REDACTED" + +class Pii < BasePii + def initialize + REDACTED_KEYS.each do |key| + instance_variable_set("@#{key}", VALUE) + end + end +end diff --git a/utils/build/docker/ruby/rails70/config/routes.rb b/utils/build/docker/ruby/rails70/config/routes.rb index 717c4b77dae..5624e4b3e19 100644 --- a/utils/build/docker/ruby/rails70/config/routes.rb +++ b/utils/build/docker/ruby/rails70/config/routes.rb @@ -7,6 +7,8 @@ get '/' => 'system_test#root' post '/' => 'system_test#root' + get '/healthcheck' => 'system_test#healthcheck' + get '/waf' => 'system_test#waf' post '/waf' => 'system_test#waf' get '/waf/*other' => 'system_test#waf' @@ -22,25 +24,32 @@ get '/make_distant_call' => 'system_test#make_distant_call' get '/headers' => 'system_test#test_headers' - get '/identify' => 'system_test#identify' + get '/identify' => 'system_test#identify' get 'user_login_success_event' => 'system_test#user_login_success_event' get 'user_login_failure_event' => 'system_test#user_login_failure_event' get 'custom_event' => 'system_test#custom_event' - %i(get post).each do |request_method| + %i[get post].each do |request_method| send(request_method, '/tag_value/:tag_value/:status_code' => 'system_test#tag_value') end - match '/tag_value/:tag_value/:status_code' => 'system_test#tag_value', via: :options - get '/users' => 'system_test#users' devise_for :users - %i(get post).each do |request_method| + %i[get post].each do |request_method| # We have to provide format: false to make sure the Test_DiscoveryScan test do not break # https://github.com/DataDog/system-tests/blob/515310b5fb1fd0792fc283c9ee134ab3803d6e7c/tests/appsec/waf/test_rules.py#L374 - # The test hits '/login.pwd' and expects a 404. By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists + # The test hits '/login.pwd' and expects a 404. + # By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists send(request_method, '/login' => 'system_test#login', format: false) end + + get '/requestdownstream' => 'system_test#request_downstream' + get '/returnheaders' => 'system_test#return_headers' + + get '/debugger/init' => 'debugger#init' + get '/debugger/pii' => 'debugger#pii' + get '/debugger/log' => 'debugger#log_probe' + get '/debugger/mix/:string_arg/:int_arg' => 'debugger#mix_probe' end diff --git a/utils/build/docker/ruby/rails70/db/schema.rb b/utils/build/docker/ruby/rails70/db/schema.rb new file mode 100644 index 00000000000..47ee9dc5922 --- /dev/null +++ b/utils/build/docker/ruby/rails70/db/schema.rb @@ -0,0 +1,28 @@ +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 2023_06_21_141816) do + + create_table "users", id: :string, force: :cascade do |t| + t.string "username", default: "", null: false + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false + t.string "reset_password_token" + t.datetime "reset_password_sent_at", precision: 6 + t.datetime "remember_created_at", precision: 6 + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["email"], name: "index_users_on_email", unique: true + t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true + end + +end diff --git a/utils/build/docker/ruby/rails71.Dockerfile b/utils/build/docker/ruby/rails71.Dockerfile index f4e66f2e8aa..92c860ebab6 100644 --- a/utils/build/docker/ruby/rails71.Dockerfile +++ b/utils/build/docker/ruby/rails71.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:3.2.0-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:3.2 RUN apt-get update && apt-get install -y nodejs npm diff --git a/utils/build/docker/ruby/rails71/Gemfile b/utils/build/docker/ruby/rails71/Gemfile index bf774ad6a60..1839f82d86d 100644 --- a/utils/build/docker/ruby/rails71/Gemfile +++ b/utils/build/docker/ruby/rails71/Gemfile @@ -28,7 +28,7 @@ gem "stimulus-rails" gem "jbuilder" # Talk with Kafka for propagation tests -gem "ruby-kafka" +gem "rdkafka" # Use Redis adapter to run Action Cable in production # gem "redis", "~> 4.0" diff --git a/utils/build/docker/ruby/rails71/app/controllers/system_test_controller.rb b/utils/build/docker/ruby/rails71/app/controllers/system_test_controller.rb index 1da71d87b31..ce0f1331bb2 100644 --- a/utils/build/docker/ruby/rails71/app/controllers/system_test_controller.rb +++ b/utils/build/docker/ruby/rails71/app/controllers/system_test_controller.rb @@ -1,5 +1,7 @@ +require 'json' + require 'datadog/kit/appsec/events' -require 'kafka' +require 'rdkafka' class SystemTestController < ApplicationController skip_before_action :verify_authenticity_token @@ -8,6 +10,19 @@ def root render plain: 'Hello, world!' end + def healthcheck + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + render json: { + status: 'ok', + library: { + language: 'ruby', + version: version + } + } + end + def waf render plain: 'Hello, world!' end @@ -172,45 +187,88 @@ def login def kafka_produce - kafka_client = Kafka.new(["kafka:9092"], client_id: "system-tests-client-producer") + config = { + :"bootstrap.servers" => "kafka:9092", + :"client.id" => "system-tests-client-producer", + :"group.id" => "system-tests-group", + } topic = request.params["topic"] + producer = Rdkafka::Config.new(config).producer stop = false while stop == false + delivery_handles = [] begin Datadog::Tracing.trace('kafka_produce') do |span| - kafka_client.deliver_message("Hello, world!", topic: topic) + delivery_handles << producer.produce( + topic: topic, + payload: "Hello, world!", + ) # This has to be done manually for now, because ruby does not add the topic # to the span at all span.set_tag("span.kind", "producer") span.set_tag("kafka.topic", topic) stop = true end - rescue Kafka::LeaderNotAvailable + rescue Rdkafka::BaseError end + delivery_handles.each(&:wait) end + producer.close render plain: "Done" end def kafka_consume - kafka_client = Kafka.new(["kafka:9092"], client_id: "system-tests-client-consumer") + config = { + :"bootstrap.servers" => "kafka:9092", + :"client.id" => "system-tests-client-consumer", + :"group.id" => "system-tests-group", + :"auto.offset.reset" => "earliest", + } topic = request.params["topic"] - consumer = kafka_client.consumer(group_id: "system-tests-group") + consumer = Rdkafka::Config.new(config).consumer consumer.subscribe(topic) begin - consumer.each_message do |message| + consumer.each do |message| if not message.nil? + Datadog::Tracing.trace('kafka_consume') do |span| + span.set_tag("span.kind", "consumer") + span.set_tag("kafka.topic", topic) + end break end end rescue Exception => e puts "An error has occurred while consuming messages from Kafka: #{e}" ensure - consumer.stop + consumer.close end render plain: "Done" end + def request_downstream + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + render json: ext_response.body, content_type: 'application/json' + end + + def return_headers + request_headers = request.headers.each.to_h.select do |k, _v| + k.start_with?('HTTP_') || k == 'CONTENT_TYPE' || k == 'CONTENT_LENGTH' + end + request_headers = request_headers.transform_keys do |k| + k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') + end + render json: JSON.generate(request_headers), content_type: 'application/json' + end end diff --git a/utils/build/docker/ruby/rails71/config/routes.rb b/utils/build/docker/ruby/rails71/config/routes.rb index 717c4b77dae..22c3f8c1265 100644 --- a/utils/build/docker/ruby/rails71/config/routes.rb +++ b/utils/build/docker/ruby/rails71/config/routes.rb @@ -7,6 +7,8 @@ get '/' => 'system_test#root' post '/' => 'system_test#root' + get '/healthcheck' => 'system_test#healthcheck' + get '/waf' => 'system_test#waf' post '/waf' => 'system_test#waf' get '/waf/*other' => 'system_test#waf' @@ -22,25 +24,27 @@ get '/make_distant_call' => 'system_test#make_distant_call' get '/headers' => 'system_test#test_headers' - get '/identify' => 'system_test#identify' + get '/identify' => 'system_test#identify' get 'user_login_success_event' => 'system_test#user_login_success_event' get 'user_login_failure_event' => 'system_test#user_login_failure_event' get 'custom_event' => 'system_test#custom_event' - %i(get post).each do |request_method| + %i[get post].each do |request_method| send(request_method, '/tag_value/:tag_value/:status_code' => 'system_test#tag_value') end - match '/tag_value/:tag_value/:status_code' => 'system_test#tag_value', via: :options - get '/users' => 'system_test#users' devise_for :users - %i(get post).each do |request_method| + %i[get post].each do |request_method| # We have to provide format: false to make sure the Test_DiscoveryScan test do not break # https://github.com/DataDog/system-tests/blob/515310b5fb1fd0792fc283c9ee134ab3803d6e7c/tests/appsec/waf/test_rules.py#L374 - # The test hits '/login.pwd' and expects a 404. By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists + # The test hits '/login.pwd' and expects a 404. + # By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists send(request_method, '/login' => 'system_test#login', format: false) end + + get '/requestdownstream' => 'system_test#request_downstream' + get '/returnheaders' => 'system_test#return_headers' end diff --git a/utils/build/docker/ruby/rails72.Dockerfile b/utils/build/docker/ruby/rails72.Dockerfile new file mode 100644 index 00000000000..f1c4be3c937 --- /dev/null +++ b/utils/build/docker/ruby/rails72.Dockerfile @@ -0,0 +1,19 @@ +FROM ghcr.io/datadog/images-rb/engines/ruby:3.3 + +RUN apt-get update && apt-get install -y nodejs npm + +RUN mkdir -p /app +WORKDIR /app + +COPY utils/build/docker/ruby/rails72/ . +COPY utils/build/docker/ruby/install_ddtrace.sh binaries* /binaries/ +RUN /binaries/install_ddtrace.sh + +ENV DD_TRACE_HEADER_TAGS=user-agent +ENV RAILS_ENV=production +ENV RAILS_MASTER_KEY=9d319c57ec128e905d9e2ce5742bf2de +RUN bundle exec rails db:create db:migrate db:seed + +RUN echo "#!/bin/bash\nbundle exec puma -b tcp://0.0.0.0 -p 7777 -w 1" > app.sh +RUN chmod +x app.sh +CMD [ "./app.sh" ] diff --git a/utils/build/docker/ruby/rails72/.dockerignore b/utils/build/docker/ruby/rails72/.dockerignore new file mode 100644 index 00000000000..df27d2d07dc --- /dev/null +++ b/utils/build/docker/ruby/rails72/.dockerignore @@ -0,0 +1,4 @@ +.envrc +shell.nix +vendor/bundle +node_modules diff --git a/utils/build/docker/ruby/rails72/.gitattributes b/utils/build/docker/ruby/rails72/.gitattributes new file mode 100644 index 00000000000..31eeee0b6ac --- /dev/null +++ b/utils/build/docker/ruby/rails72/.gitattributes @@ -0,0 +1,7 @@ +# See https://git-scm.com/docs/gitattributes for more about git attribute files. + +# Mark the database schema as having been generated. +db/schema.rb linguist-generated + +# Mark any vendored files as having been vendored. +vendor/* linguist-vendored diff --git a/utils/build/docker/ruby/rails72/.gitignore b/utils/build/docker/ruby/rails72/.gitignore new file mode 100644 index 00000000000..67ca8a3bfe0 --- /dev/null +++ b/utils/build/docker/ruby/rails72/.gitignore @@ -0,0 +1,39 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile '~/.gitignore_global' + +# Ignore bundler config. +/.bundle + +# Ignore the default SQLite database. +/db/*.sqlite3 +/db/*.sqlite3-* + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore pidfiles, but keep the directory. +/tmp/pids/* +!/tmp/pids/ +!/tmp/pids/.keep + +# Ignore uploaded files in development. +/storage/* +!/storage/.keep +/tmp/storage/* +!/tmp/storage/ +!/tmp/storage/.keep + +/public/assets + +# Ignore master key for decrypting credentials and more. +/config/master.key + +.envrc +shell.nix +/vendor/bundle diff --git a/utils/build/docker/ruby/rails72/.ruby-version b/utils/build/docker/ruby/rails72/.ruby-version new file mode 100644 index 00000000000..e391e1801dc --- /dev/null +++ b/utils/build/docker/ruby/rails72/.ruby-version @@ -0,0 +1 @@ +ruby-3.3.6 diff --git a/utils/build/docker/ruby/rails72/Gemfile b/utils/build/docker/ruby/rails72/Gemfile new file mode 100644 index 00000000000..f13ee50ddbf --- /dev/null +++ b/utils/build/docker/ruby/rails72/Gemfile @@ -0,0 +1,80 @@ +source "https://rubygems.org" +git_source(:github) { |repo| "https://github.com/#{repo}.git" } + +ruby "~> 3.3.0" + +# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" +gem "rails", "~> 7.2.2" + +# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] +gem "sprockets-rails" + +# Use sqlite3 as the database for Active Record +gem "sqlite3", "~> 1.4" + +# Use the Puma web server [https://github.com/puma/puma] +gem "puma", "~> 6.0" + +# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] +gem "importmap-rails" + +# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] +gem "turbo-rails" + +# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] +gem "stimulus-rails" + +# Build JSON APIs with ease [https://github.com/rails/jbuilder] +gem "jbuilder" + +# Talk with Kafka for propagation tests +gem "rdkafka" + +# Use Redis adapter to run Action Cable in production +# gem "redis", "~> 4.0" + +# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] +# gem "kredis" + +# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] +# gem "bcrypt", "~> 3.1.7" + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ] + +# Reduces boot times through caching; required in config/boot.rb +gem "bootsnap", require: false + +# Use Sass to process CSS +# gem "sassc-rails" + +# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] +# gem "image_processing", "~> 1.2" + +group :development, :test do + # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem + gem "debug", platforms: %i[ mri mingw x64_mingw ] +end + +group :development do + # Use console on exceptions pages [https://github.com/rails/web-console] + gem "web-console" + + # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler] + # gem "rack-mini-profiler" + + # Speed up commands on slow machines / big apps [https://github.com/rails/spring] + # gem "spring" +end + +group :test do + # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] + gem "capybara" + gem "selenium-webdriver" + gem "webdrivers" +end + +gem 'devise' + +gem 'pry' +gem 'datadog', '~> 2.7.0', require: 'datadog/auto_instrument' diff --git a/utils/build/docker/ruby/rails72/Gemfile.lock b/utils/build/docker/ruby/rails72/Gemfile.lock new file mode 100644 index 00000000000..be2f94a656e --- /dev/null +++ b/utils/build/docker/ruby/rails72/Gemfile.lock @@ -0,0 +1,325 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (7.2.2) + actionpack (= 7.2.2) + activesupport (= 7.2.2) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + zeitwerk (~> 2.6) + actionmailbox (7.2.2) + actionpack (= 7.2.2) + activejob (= 7.2.2) + activerecord (= 7.2.2) + activestorage (= 7.2.2) + activesupport (= 7.2.2) + mail (>= 2.8.0) + actionmailer (7.2.2) + actionpack (= 7.2.2) + actionview (= 7.2.2) + activejob (= 7.2.2) + activesupport (= 7.2.2) + mail (>= 2.8.0) + rails-dom-testing (~> 2.2) + actionpack (7.2.2) + actionview (= 7.2.2) + activesupport (= 7.2.2) + nokogiri (>= 1.8.5) + racc + rack (>= 2.2.4, < 3.2) + rack-session (>= 1.0.1) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + useragent (~> 0.16) + actiontext (7.2.2) + actionpack (= 7.2.2) + activerecord (= 7.2.2) + activestorage (= 7.2.2) + activesupport (= 7.2.2) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (7.2.2) + activesupport (= 7.2.2) + builder (~> 3.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (7.2.2) + activesupport (= 7.2.2) + globalid (>= 0.3.6) + activemodel (7.2.2) + activesupport (= 7.2.2) + activerecord (7.2.2) + activemodel (= 7.2.2) + activesupport (= 7.2.2) + timeout (>= 0.4.0) + activestorage (7.2.2) + actionpack (= 7.2.2) + activejob (= 7.2.2) + activerecord (= 7.2.2) + activesupport (= 7.2.2) + marcel (~> 1.0) + activesupport (7.2.2) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + base64 (0.2.0) + bcrypt (3.1.20) + benchmark (0.4.0) + bigdecimal (3.1.8) + bindex (0.8.1) + bootsnap (1.18.4) + msgpack (~> 1.2) + builder (3.3.0) + capybara (3.40.0) + addressable + matrix + mini_mime (>= 0.1.3) + nokogiri (~> 1.11) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (>= 1.5, < 3.0) + xpath (~> 3.2) + coderay (1.1.3) + concurrent-ruby (1.3.4) + connection_pool (2.4.1) + crass (1.0.6) + date (3.4.0) + ddtrace (1.0.0) + debase-ruby_core_source (<= 0.10.15) + libddwaf (~> 1.3.0.0.0.a) + msgpack + debase-ruby_core_source (0.10.15) + debug (1.9.2) + irb (~> 1.10) + reline (>= 0.3.8) + devise (4.9.4) + bcrypt (~> 3.0) + orm_adapter (~> 0.1) + railties (>= 4.1.0) + responders + warden (~> 1.2.3) + drb (2.2.1) + erubi (1.13.0) + ffi (1.17.0) + ffi (1.17.0-aarch64-linux-gnu) + ffi (1.17.0-arm64-darwin) + ffi (1.17.0-x86_64-darwin) + ffi (1.17.0-x86_64-linux-gnu) + globalid (1.2.1) + activesupport (>= 6.1) + i18n (1.14.6) + concurrent-ruby (~> 1.0) + importmap-rails (2.0.3) + actionpack (>= 6.0.0) + activesupport (>= 6.0.0) + railties (>= 6.0.0) + io-console (0.7.2) + irb (1.14.1) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + jbuilder (2.13.0) + actionview (>= 5.0.0) + activesupport (>= 5.0.0) + libddwaf (1.3.0.0.0) + ffi (~> 1.0) + libddwaf (1.3.0.0.0-aarch64-linux) + ffi (~> 1.0) + libddwaf (1.3.0.0.0-arm64-darwin) + ffi (~> 1.0) + libddwaf (1.3.0.0.0-x86_64-darwin) + ffi (~> 1.0) + libddwaf (1.3.0.0.0-x86_64-linux) + ffi (~> 1.0) + logger (1.6.1) + loofah (2.23.1) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + mail (2.8.1) + mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp + marcel (1.0.4) + matrix (0.4.2) + method_source (1.1.0) + mini_mime (1.1.5) + mini_portile2 (2.8.8) + minitest (5.25.1) + msgpack (1.7.5) + net-imap (0.5.1) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-smtp (0.5.0) + net-protocol + nio4r (2.7.4) + nokogiri (1.16.7) + mini_portile2 (~> 2.8.2) + racc (~> 1.4) + nokogiri (1.16.7-aarch64-linux) + racc (~> 1.4) + nokogiri (1.16.7-arm64-darwin) + racc (~> 1.4) + nokogiri (1.16.7-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.16.7-x86_64-linux) + racc (~> 1.4) + orm_adapter (0.5.0) + pry (0.14.2) + coderay (~> 1.1) + method_source (~> 1.0) + psych (5.2.0) + stringio + public_suffix (6.0.1) + puma (6.4.3) + nio4r (~> 2.0) + racc (1.8.1) + rack (3.1.8) + rack-session (2.0.0) + rack (>= 3.0.0) + rack-test (2.1.0) + rack (>= 1.3) + rackup (2.2.1) + rack (>= 3) + rails (7.2.2) + actioncable (= 7.2.2) + actionmailbox (= 7.2.2) + actionmailer (= 7.2.2) + actionpack (= 7.2.2) + actiontext (= 7.2.2) + actionview (= 7.2.2) + activejob (= 7.2.2) + activemodel (= 7.2.2) + activerecord (= 7.2.2) + activestorage (= 7.2.2) + activesupport (= 7.2.2) + bundler (>= 1.15.0) + railties (= 7.2.2) + rails-dom-testing (2.2.0) + activesupport (>= 5.0.0) + minitest + nokogiri (>= 1.6) + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) + railties (7.2.2) + actionpack (= 7.2.2) + activesupport (= 7.2.2) + irb (~> 1.13) + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + rake (13.2.1) + rdkafka (0.19.0) + ffi (~> 1.15) + mini_portile2 (~> 2.6) + rake (> 12) + rdoc (6.7.0) + psych (>= 4.0.0) + regexp_parser (2.9.2) + reline (0.5.11) + io-console (~> 0.5) + responders (3.1.1) + actionpack (>= 5.2) + railties (>= 5.2) + rexml (3.3.9) + rubyzip (2.3.2) + securerandom (0.3.2) + selenium-webdriver (4.26.0) + base64 (~> 0.2) + logger (~> 1.4) + rexml (~> 3.2, >= 3.2.5) + rubyzip (>= 1.2.2, < 3.0) + websocket (~> 1.0) + sprockets (4.2.1) + concurrent-ruby (~> 1.0) + rack (>= 2.2.4, < 4) + sprockets-rails (3.5.2) + actionpack (>= 6.1) + activesupport (>= 6.1) + sprockets (>= 3.0.0) + sqlite3 (1.7.3) + mini_portile2 (~> 2.8.0) + sqlite3 (1.7.3-aarch64-linux) + sqlite3 (1.7.3-arm64-darwin) + sqlite3 (1.7.3-x86_64-darwin) + sqlite3 (1.7.3-x86_64-linux) + stimulus-rails (1.3.4) + railties (>= 6.0.0) + stringio (3.1.2) + thor (1.3.2) + timeout (0.4.2) + turbo-rails (2.0.11) + actionpack (>= 6.0.0) + railties (>= 6.0.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + useragent (0.16.10) + warden (1.2.9) + rack (>= 2.0.9) + web-console (4.2.1) + actionview (>= 6.0.0) + activemodel (>= 6.0.0) + bindex (>= 0.4.0) + railties (>= 6.0.0) + webdrivers (5.2.0) + nokogiri (~> 1.6) + rubyzip (>= 1.3.0) + selenium-webdriver (~> 4.0) + websocket (1.2.11) + websocket-driver (0.7.6) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + xpath (3.2.0) + nokogiri (~> 1.8) + zeitwerk (2.7.1) + +PLATFORMS + aarch64-linux-gnu + arm64-darwin + ruby + x86_64-darwin + x86_64-linux-gnu + +DEPENDENCIES + bootsnap + capybara + ddtrace (~> 1.0.0.a) + debug + devise + importmap-rails + jbuilder + pry + puma (~> 6.0) + rails (~> 7.2.2) + rdkafka + selenium-webdriver + sprockets-rails + sqlite3 (~> 1.4) + stimulus-rails + turbo-rails + tzinfo-data + web-console + webdrivers + +RUBY VERSION + ruby 3.3.6p108 + +BUNDLED WITH + 2.3.26 diff --git a/utils/build/docker/ruby/rails72/README.md b/utils/build/docker/ruby/rails72/README.md new file mode 100644 index 00000000000..7db80e4ca1b --- /dev/null +++ b/utils/build/docker/ruby/rails72/README.md @@ -0,0 +1,24 @@ +# README + +This README would normally document whatever steps are necessary to get the +application up and running. + +Things you may want to cover: + +* Ruby version + +* System dependencies + +* Configuration + +* Database creation + +* Database initialization + +* How to run the test suite + +* Services (job queues, cache servers, search engines, etc.) + +* Deployment instructions + +* ... diff --git a/utils/build/docker/ruby/rails72/Rakefile b/utils/build/docker/ruby/rails72/Rakefile new file mode 100644 index 00000000000..9a5ea7383aa --- /dev/null +++ b/utils/build/docker/ruby/rails72/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require_relative "config/application" + +Rails.application.load_tasks diff --git a/utils/build/docker/ruby/rails72/app/assets/config/manifest.js b/utils/build/docker/ruby/rails72/app/assets/config/manifest.js new file mode 100644 index 00000000000..ddd546a0be4 --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/assets/config/manifest.js @@ -0,0 +1,4 @@ +//= link_tree ../images +//= link_directory ../stylesheets .css +//= link_tree ../../javascript .js +//= link_tree ../../../vendor/javascript .js diff --git a/utils/build/docker/ruby/rails41/lib/assets/.keep b/utils/build/docker/ruby/rails72/app/assets/images/.keep similarity index 100% rename from utils/build/docker/ruby/rails41/lib/assets/.keep rename to utils/build/docker/ruby/rails72/app/assets/images/.keep diff --git a/utils/build/docker/ruby/rails72/app/assets/stylesheets/application.css b/utils/build/docker/ruby/rails72/app/assets/stylesheets/application.css new file mode 100644 index 00000000000..288b9ab7182 --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/assets/stylesheets/application.css @@ -0,0 +1,15 @@ +/* + * This is a manifest file that'll be compiled into application.css, which will include all the files + * listed below. + * + * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's + * vendor/assets/stylesheets directory can be referenced here using a relative path. + * + * You're free to add application-wide styles to this file and they'll appear at the bottom of the + * compiled file so the styles you add here take precedence over styles defined in any other CSS + * files in this directory. Styles in this file should be added after the last require_* statement. + * It is generally better to create a new file per style scope. + * + *= require_tree . + *= require_self + */ diff --git a/utils/build/docker/ruby/rails72/app/channels/application_cable/channel.rb b/utils/build/docker/ruby/rails72/app/channels/application_cable/channel.rb new file mode 100644 index 00000000000..d6726972830 --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/channels/application_cable/channel.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Channel < ActionCable::Channel::Base + end +end diff --git a/utils/build/docker/ruby/rails72/app/channels/application_cable/connection.rb b/utils/build/docker/ruby/rails72/app/channels/application_cable/connection.rb new file mode 100644 index 00000000000..0ff5442f476 --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/channels/application_cable/connection.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Connection < ActionCable::Connection::Base + end +end diff --git a/utils/build/docker/ruby/rails72/app/controllers/application_controller.rb b/utils/build/docker/ruby/rails72/app/controllers/application_controller.rb new file mode 100644 index 00000000000..09705d12ab4 --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/controllers/application_controller.rb @@ -0,0 +1,2 @@ +class ApplicationController < ActionController::Base +end diff --git a/utils/build/docker/ruby/rails41/lib/tasks/.keep b/utils/build/docker/ruby/rails72/app/controllers/concerns/.keep similarity index 100% rename from utils/build/docker/ruby/rails41/lib/tasks/.keep rename to utils/build/docker/ruby/rails72/app/controllers/concerns/.keep diff --git a/utils/build/docker/ruby/rails72/app/controllers/system_test_controller.rb b/utils/build/docker/ruby/rails72/app/controllers/system_test_controller.rb new file mode 100644 index 00000000000..ce0f1331bb2 --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/controllers/system_test_controller.rb @@ -0,0 +1,274 @@ +require 'json' + +require 'datadog/kit/appsec/events' +require 'rdkafka' + +class SystemTestController < ApplicationController + skip_before_action :verify_authenticity_token + + def root + render plain: 'Hello, world!' + end + + def healthcheck + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + render json: { + status: 'ok', + library: { + language: 'ruby', + version: version + } + } + end + + def waf + render plain: 'Hello, world!' + end + + def handle_path_params + render plain: 'Hello, world!' + end + + def generate_spans + begin + repeats = Integer(request.params['repeats'] || 0) + garbage = Integer(request.params['garbage'] || 0) + rescue ArgumentError + render plain: 'bad request', status: 400 + else + repeats.times do |i| + Datadog::Tracing.trace('repeat-#{i}') do |span| + garbage.times do |j| + span.set_tag("garbage-#{j}", "#{j}") + end + end + end + end + + render plain: 'Generated #{repeats} spans with #{garbage} garbage tags' + end + + def test_headers + response.set_header('Content-Type', 'text/plain') + response.set_header('Content-Length', '15') + response.set_header('Content-Language', 'en-US') + + render plain: 'Hello, headers!' + end + + def identify + trace = Datadog::Tracing.active_trace + trace.set_tag('usr.id', 'usr.id') + trace.set_tag('usr.name', 'usr.name') + trace.set_tag('usr.email', 'usr.email') + trace.set_tag('usr.session_id', 'usr.session_id') + trace.set_tag('usr.role', 'usr.role') + trace.set_tag('usr.scope', 'usr.scope') + + render plain: 'Hello, world!' + end + + def status + render plain: "Ok", status: params[:code] + end + + def read_file + render plain: File.read(params[:file]) + end + + def make_distant_call + url = params[:url] + uri = URI(url) + request = nil + response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + request = Net::HTTP::Get.new(uri) + + response = http.request(request) + end + + result = { + "url": url, + "status_code": response.code, + "request_headers": request.each_header.to_h, + "response_headers": response.each_header.to_h, + } + + render json: result + end + + def user_login_success_event + Datadog::Kit::AppSec::Events.track_login_success( + Datadog::Tracing.active_trace, user: {id: 'system_tests_user'}, metadata0: "value0", metadata1: "value1" + ) + + render plain: 'Hello, world!' + end + + def user_login_failure_event + Datadog::Kit::AppSec::Events.track_login_failure( + Datadog::Tracing.active_trace, user_id: 'system_tests_user', user_exists: true, metadata0: "value0", metadata1: "value1" + ) + + render plain: 'Hello, world!' + end + + def custom_event + Datadog::Kit::AppSec::Events.track('system_tests_event', Datadog::Tracing.active_trace, metadata0: "value0", metadata1: "value1") + + render plain: 'Hello, world!' + end + + def tag_value + event_value = params[:tag_value] + status_code = params[:status_code] + + if request.method == "POST" && event_value.include?('payload_in_response_body') + render json: { payload: request.POST } + return + end + + headers = request.query_string.split('&').map {|e | e.split('=')} || [] + + trace = Datadog::Tracing.active_trace + trace.set_tag("appsec.events.system_tests_appsec_event.value", event_value) + + headers.each do |key, value| + response.set_header(key, value) + end + + render plain: 'Value tagged', status: status_code + end + + def users + user_id = request.params["user"] + + Datadog::Kit::Identity.set_user(id: user_id) + + render plain: 'Hello, user!' + end + + def login + request.env["devise.allow_params_authentication"] = true + + sdk_event = request.params[:sdk_event] + sdk_user = request.params[:sdk_user] + sdk_email = request.params[:sdk_mail] + sdk_exists = request.params[:sdk_user_exists] + + if sdk_exists + sdk_exists = sdk_exists == "true" + end + + result = request.env['warden'].authenticate({ scope: Devise.mappings[:user].name }) + + if sdk_event === 'failure' && sdk_user + metadata = {} + metadata[:email] = sdk_email if sdk_email + Datadog::Kit::AppSec::Events.track_login_failure(user_id: sdk_user, user_exists: sdk_exists, **metadata) + elsif sdk_event === 'success' && sdk_user + user = {} + user[:id] = sdk_user + user[:email] = sdk_email if sdk_email + Datadog::Kit::AppSec::Events.track_login_success(user: user) + end + + unless result + render plain: '', status: 401 + return + end + + + render plain: 'Hello, world!' + end + + + def kafka_produce + config = { + :"bootstrap.servers" => "kafka:9092", + :"client.id" => "system-tests-client-producer", + :"group.id" => "system-tests-group", + } + topic = request.params["topic"] + producer = Rdkafka::Config.new(config).producer + stop = false + while stop == false + delivery_handles = [] + begin + Datadog::Tracing.trace('kafka_produce') do |span| + delivery_handles << producer.produce( + topic: topic, + payload: "Hello, world!", + ) + # This has to be done manually for now, because ruby does not add the topic + # to the span at all + span.set_tag("span.kind", "producer") + span.set_tag("kafka.topic", topic) + stop = true + end + rescue Rdkafka::BaseError + end + delivery_handles.each(&:wait) + end + producer.close + + render plain: "Done" + end + + + def kafka_consume + config = { + :"bootstrap.servers" => "kafka:9092", + :"client.id" => "system-tests-client-consumer", + :"group.id" => "system-tests-group", + :"auto.offset.reset" => "earliest", + } + topic = request.params["topic"] + consumer = Rdkafka::Config.new(config).consumer + consumer.subscribe(topic) + begin + consumer.each do |message| + if not message.nil? + Datadog::Tracing.trace('kafka_consume') do |span| + span.set_tag("span.kind", "consumer") + span.set_tag("kafka.topic", topic) + end + break + end + end + rescue Exception => e + puts "An error has occurred while consuming messages from Kafka: #{e}" + ensure + consumer.close + end + + render plain: "Done" + end + + def request_downstream + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + render json: ext_response.body, content_type: 'application/json' + end + + def return_headers + request_headers = request.headers.each.to_h.select do |k, _v| + k.start_with?('HTTP_') || k == 'CONTENT_TYPE' || k == 'CONTENT_LENGTH' + end + request_headers = request_headers.transform_keys do |k| + k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') + end + render json: JSON.generate(request_headers), content_type: 'application/json' + end +end diff --git a/utils/build/docker/ruby/rails40/app/helpers/application_helper.rb b/utils/build/docker/ruby/rails72/app/helpers/application_helper.rb similarity index 100% rename from utils/build/docker/ruby/rails40/app/helpers/application_helper.rb rename to utils/build/docker/ruby/rails72/app/helpers/application_helper.rb diff --git a/utils/build/docker/ruby/rails72/app/javascript/application.js b/utils/build/docker/ruby/rails72/app/javascript/application.js new file mode 100644 index 00000000000..0d7b49404c3 --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/javascript/application.js @@ -0,0 +1,3 @@ +// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails +import "@hotwired/turbo-rails" +import "controllers" diff --git a/utils/build/docker/ruby/rails72/app/javascript/controllers/application.js b/utils/build/docker/ruby/rails72/app/javascript/controllers/application.js new file mode 100644 index 00000000000..1213e85c7ac --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/javascript/controllers/application.js @@ -0,0 +1,9 @@ +import { Application } from "@hotwired/stimulus" + +const application = Application.start() + +// Configure Stimulus development experience +application.debug = false +window.Stimulus = application + +export { application } diff --git a/utils/build/docker/ruby/rails72/app/javascript/controllers/hello_controller.js b/utils/build/docker/ruby/rails72/app/javascript/controllers/hello_controller.js new file mode 100644 index 00000000000..5975c0789d7 --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/javascript/controllers/hello_controller.js @@ -0,0 +1,7 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + connect() { + this.element.textContent = "Hello World!" + } +} diff --git a/utils/build/docker/ruby/rails72/app/javascript/controllers/index.js b/utils/build/docker/ruby/rails72/app/javascript/controllers/index.js new file mode 100644 index 00000000000..54ad4cad4d4 --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/javascript/controllers/index.js @@ -0,0 +1,11 @@ +// Import and register all your controllers from the importmap under controllers/* + +import { application } from "controllers/application" + +// Eager load all controllers defined in the import map under controllers/**/*_controller +import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading" +eagerLoadControllersFrom("controllers", application) + +// Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!) +// import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading" +// lazyLoadControllersFrom("controllers", application) diff --git a/utils/build/docker/ruby/rails72/app/jobs/application_job.rb b/utils/build/docker/ruby/rails72/app/jobs/application_job.rb new file mode 100644 index 00000000000..d394c3d1062 --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/jobs/application_job.rb @@ -0,0 +1,7 @@ +class ApplicationJob < ActiveJob::Base + # Automatically retry jobs that encountered a deadlock + # retry_on ActiveRecord::Deadlocked + + # Most jobs are safe to ignore if the underlying records are no longer available + # discard_on ActiveJob::DeserializationError +end diff --git a/utils/build/docker/ruby/rails72/app/mailers/application_mailer.rb b/utils/build/docker/ruby/rails72/app/mailers/application_mailer.rb new file mode 100644 index 00000000000..3c34c8148f1 --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: "from@example.com" + layout "mailer" +end diff --git a/utils/build/docker/ruby/rails72/app/models/application_record.rb b/utils/build/docker/ruby/rails72/app/models/application_record.rb new file mode 100644 index 00000000000..b63caeb8a5c --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + primary_abstract_class +end diff --git a/utils/build/docker/ruby/rails41/test/controllers/.keep b/utils/build/docker/ruby/rails72/app/models/concerns/.keep similarity index 100% rename from utils/build/docker/ruby/rails41/test/controllers/.keep rename to utils/build/docker/ruby/rails72/app/models/concerns/.keep diff --git a/utils/build/docker/ruby/rails72/app/models/user.rb b/utils/build/docker/ruby/rails72/app/models/user.rb new file mode 100644 index 00000000000..47567994e9c --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/models/user.rb @@ -0,0 +1,6 @@ +class User < ApplicationRecord + # Include default devise modules. Others available are: + # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable + devise :database_authenticatable, :registerable, + :recoverable, :rememberable, :validatable +end diff --git a/utils/build/docker/ruby/rails72/app/views/layouts/application.html.erb b/utils/build/docker/ruby/rails72/app/views/layouts/application.html.erb new file mode 100644 index 00000000000..0d2f3c9bdb9 --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/views/layouts/application.html.erb @@ -0,0 +1,16 @@ + + + + Rails70 + + <%= csrf_meta_tags %> + <%= csp_meta_tag %> + + <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> + <%= javascript_importmap_tags %> + + + + <%= yield %> + + diff --git a/utils/build/docker/ruby/rails72/app/views/layouts/mailer.html.erb b/utils/build/docker/ruby/rails72/app/views/layouts/mailer.html.erb new file mode 100644 index 00000000000..cbd34d2e9dd --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/views/layouts/mailer.html.erb @@ -0,0 +1,13 @@ + + + + + + + + + <%= yield %> + + diff --git a/utils/build/docker/ruby/rails72/app/views/layouts/mailer.text.erb b/utils/build/docker/ruby/rails72/app/views/layouts/mailer.text.erb new file mode 100644 index 00000000000..37f0bddbd74 --- /dev/null +++ b/utils/build/docker/ruby/rails72/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/utils/build/docker/ruby/rails72/bin/rails b/utils/build/docker/ruby/rails72/bin/rails new file mode 100755 index 00000000000..efc0377492f --- /dev/null +++ b/utils/build/docker/ruby/rails72/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path("../config/application", __dir__) +require_relative "../config/boot" +require "rails/commands" diff --git a/utils/build/docker/ruby/rails72/config.ru b/utils/build/docker/ruby/rails72/config.ru new file mode 100644 index 00000000000..4a3c09a6889 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config.ru @@ -0,0 +1,6 @@ +# This file is used by Rack-based servers to start the application. + +require_relative "config/environment" + +run Rails.application +Rails.application.load_server diff --git a/utils/build/docker/ruby/rails72/config/application.rb b/utils/build/docker/ruby/rails72/config/application.rb new file mode 100644 index 00000000000..1f0390ac072 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/application.rb @@ -0,0 +1,22 @@ +require_relative "boot" + +require "rails/all" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module Rails70 + class Application < Rails::Application + # Initialize configuration defaults for originally generated Rails version. + config.load_defaults 7.0 + + # Configuration for the application, engines, and railties goes here. + # + # These settings can be overridden in specific environments using the files + # in config/environments, which are processed later. + # + # config.time_zone = "Central Time (US & Canada)" + # config.eager_load_paths << Rails.root.join("extras") + end +end diff --git a/utils/build/docker/ruby/rails72/config/boot.rb b/utils/build/docker/ruby/rails72/config/boot.rb new file mode 100644 index 00000000000..988a5ddc460 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/boot.rb @@ -0,0 +1,4 @@ +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +require "bundler/setup" # Set up gems listed in the Gemfile. +require "bootsnap/setup" # Speed up boot time by caching expensive operations. diff --git a/utils/build/docker/ruby/rails72/config/cable.yml b/utils/build/docker/ruby/rails72/config/cable.yml new file mode 100644 index 00000000000..8ea8617f58f --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/cable.yml @@ -0,0 +1,10 @@ +development: + adapter: async + +test: + adapter: test + +production: + adapter: redis + url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> + channel_prefix: rails70_production diff --git a/utils/build/docker/ruby/rails72/config/credentials.yml.enc b/utils/build/docker/ruby/rails72/config/credentials.yml.enc new file mode 100644 index 00000000000..aeb5eb19e65 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/credentials.yml.enc @@ -0,0 +1 @@ +G5RovwV49vRCRsWk/HDncp0URlHKknKKjpxxP5znIc/TKR+dvGVoevXlv7QrfaJG1X8gq4nnL1uahrEwFNtqc5qVrTeM/GrFoY5UUthoIjDNTG8CboZEpCfvlo5n7qC1Tm3SnkxCR4q0c1Hpq7GFkRnpPRhK/Y69Xd/2TyHirAHGKPfWb27aS77VXtFO7Haho9NnL3mB5PPn1VEIQnwBAhRggeQF6hs460e6tS5nZiKsa3QOO1G86Q1sU7k3AF/J+cG/NIT555LI3Wso7qU80KySor4j/IY+DVe7jys8XB9frX5ppt2vfnRc/F5indCRUrT7N8wXdLx7C1eOxyWNLKt2L9fmt1JYauOlI/GZ9YJWtqqAkPDsssYuUc8F6ZeIZQQTxHWeFd4MJZVplFKDrG20lUROIAz41nAM--qxpsBmnjgm5xqiYc--Dow+e/9K97oMj5VdQge/tQ== \ No newline at end of file diff --git a/utils/build/docker/ruby/rails72/config/database.yml b/utils/build/docker/ruby/rails72/config/database.yml new file mode 100644 index 00000000000..fcba57f19f0 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/database.yml @@ -0,0 +1,25 @@ +# SQLite. Versions 3.8.0 and up are supported. +# gem install sqlite3 +# +# Ensure the SQLite 3 gem is defined in your Gemfile +# gem "sqlite3" +# +default: &default + adapter: sqlite3 + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + timeout: 5000 + +development: + <<: *default + database: db/development.sqlite3 + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: db/test.sqlite3 + +production: + <<: *default + database: db/production.sqlite3 diff --git a/utils/build/docker/ruby/rails72/config/environment.rb b/utils/build/docker/ruby/rails72/config/environment.rb new file mode 100644 index 00000000000..cac53157752 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require_relative "application" + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/utils/build/docker/ruby/rails72/config/environments/development.rb b/utils/build/docker/ruby/rails72/config/environments/development.rb new file mode 100644 index 00000000000..5e311ae21d2 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/environments/development.rb @@ -0,0 +1,72 @@ +require "active_support/core_ext/integer/time" + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded any time + # it changes. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports. + config.consider_all_requests_local = true + + # Enable server timing + config.server_timing = true + + # Enable/disable caching. By default caching is disabled. + # Run rails dev:cache to toggle caching. + if Rails.root.join("tmp/caching-dev.txt").exist? + config.action_controller.perform_caching = true + config.action_controller.enable_fragment_cache_logging = true + + config.cache_store = :memory_store + config.public_file_server.headers = { + "Cache-Control" => "public, max-age=#{2.days.to_i}" + } + else + config.action_controller.perform_caching = false + + config.cache_store = :null_store + end + + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = :local + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + config.action_mailer.perform_caching = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + + # Suppress logger output for asset requests. + config.assets.quiet = true + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true + + # Uncomment if you wish to allow Action Cable access from any origin. + # config.action_cable.disable_request_forgery_protection = true + + config.hosts.clear +end diff --git a/utils/build/docker/ruby/rails72/config/environments/production.rb b/utils/build/docker/ruby/rails72/config/environments/production.rb new file mode 100644 index 00000000000..e58961b3138 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/environments/production.rb @@ -0,0 +1,93 @@ +require "active_support/core_ext/integer/time" + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] + # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # config.require_master_key = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? + + # Compress CSS using a preprocessor. + # config.assets.css_compressor = :sass + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = false + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.asset_host = "http://assets.example.com" + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache + # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX + + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = :local + + # Mount Action Cable outside main process or domain. + # config.action_cable.mount_path = nil + # config.action_cable.url = "wss://example.com/cable" + # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Include generic and useful information about system operation, but avoid logging too much + # information to avoid inadvertent exposure of personally identifiable information (PII). + config.log_level = :info + + # Prepend all log lines with the following tags. + config.log_tags = [ :request_id ] + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Use a real queuing backend for Active Job (and separate queues per environment). + # config.active_job.queue_adapter = :resque + # config.active_job.queue_name_prefix = "rails70_production" + + config.action_mailer.perform_caching = false + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Don't log any deprecations. + config.active_support.report_deprecations = false + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Use a different logger for distributed setups. + # require "syslog/logger" + # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new "app-name") + + if ENV["RAILS_LOG_TO_STDOUT"].present? + logger = ActiveSupport::Logger.new(STDOUT) + logger.formatter = config.log_formatter + config.logger = ActiveSupport::TaggedLogging.new(logger) + end + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false +end diff --git a/utils/build/docker/ruby/rails72/config/environments/test.rb b/utils/build/docker/ruby/rails72/config/environments/test.rb new file mode 100644 index 00000000000..6ea4d1e7063 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/environments/test.rb @@ -0,0 +1,60 @@ +require "active_support/core_ext/integer/time" + +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Turn false under Spring and add config.action_view.cache_template_loading = true. + config.cache_classes = true + + # Eager loading loads your whole application. When running a single test locally, + # this probably isn't necessary. It's a good idea to do in a continuous integration + # system, or in some way before deploying your code. + config.eager_load = ENV["CI"].present? + + # Configure public file server for tests with Cache-Control for performance. + config.public_file_server.enabled = true + config.public_file_server.headers = { + "Cache-Control" => "public, max-age=#{1.hour.to_i}" + } + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + config.cache_store = :null_store + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Store uploaded files on the local file system in a temporary directory. + config.active_storage.service = :test + + config.action_mailer.perform_caching = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true +end diff --git a/utils/build/docker/ruby/rails72/config/importmap.rb b/utils/build/docker/ruby/rails72/config/importmap.rb new file mode 100644 index 00000000000..8dce42d4060 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/importmap.rb @@ -0,0 +1,7 @@ +# Pin npm packages by running ./bin/importmap + +pin "application", preload: true +pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true +pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true +pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true +pin_all_from "app/javascript/controllers", under: "controllers" diff --git a/utils/build/docker/ruby/rails72/config/initializers/assets.rb b/utils/build/docker/ruby/rails72/config/initializers/assets.rb new file mode 100644 index 00000000000..2eeef966fe8 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/initializers/assets.rb @@ -0,0 +1,12 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = "1.0" + +# Add additional assets to the asset load path. +# Rails.application.config.assets.paths << Emoji.images_path + +# Precompile additional assets. +# application.js, application.css, and all non-JS/CSS in the app/assets +# folder are already added. +# Rails.application.config.assets.precompile += %w( admin.js admin.css ) diff --git a/utils/build/docker/ruby/rails72/config/initializers/content_security_policy.rb b/utils/build/docker/ruby/rails72/config/initializers/content_security_policy.rb new file mode 100644 index 00000000000..3621f97f8e9 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/initializers/content_security_policy.rb @@ -0,0 +1,26 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide content security policy +# For further information see the following documentation +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy + +# Rails.application.configure do +# config.content_security_policy do |policy| +# policy.default_src :self, :https +# policy.font_src :self, :https, :data +# policy.img_src :self, :https, :data +# policy.object_src :none +# policy.script_src :self, :https +# policy.style_src :self, :https +# # Specify URI for violation reports +# # policy.report_uri "/csp-violation-report-endpoint" +# end +# +# # Generate session nonces for permitted importmap and inline scripts +# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } +# config.content_security_policy_nonce_directives = %w(script-src) +# +# # Report CSP violations to a specified URI. See: +# # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only +# # config.content_security_policy_report_only = true +# end diff --git a/utils/build/docker/ruby/rails32/config/initializers/datadog.rb b/utils/build/docker/ruby/rails72/config/initializers/datadog.rb similarity index 100% rename from utils/build/docker/ruby/rails32/config/initializers/datadog.rb rename to utils/build/docker/ruby/rails72/config/initializers/datadog.rb diff --git a/utils/build/docker/ruby/rails72/config/initializers/devise.rb b/utils/build/docker/ruby/rails72/config/initializers/devise.rb new file mode 100644 index 00000000000..098e4a0aa67 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/initializers/devise.rb @@ -0,0 +1,313 @@ +# frozen_string_literal: true + +# Assuming you have not yet modified this file, each configuration option below +# is set to its default value. Note that some are commented out while others +# are not: uncommented lines are intended to protect your configuration from +# breaking changes in upgrades (i.e., in the event that future versions of +# Devise change the default values for those options). +# +# Use this hook to configure devise mailer, warden hooks and so forth. +# Many of these configuration options can be set straight in your model. +Devise.setup do |config| + # The secret key used by Devise. Devise uses this key to generate + # random tokens. Changing this key will render invalid all existing + # confirmation, reset password and unlock tokens in the database. + # Devise will use the `secret_key_base` as its `secret_key` + # by default. You can change it below and use your own secret key. + # config.secret_key = '2aa7763a03b8aeefb5507ab110519240bbd9c017f8c15c8e5d652871ebdc194735d7acda52f0a3eef7a46fb2f16bc4a0eeacd1542a3f63ad6d56e38a15484fa8' + + # ==> Controller configuration + # Configure the parent class to the devise controllers. + # config.parent_controller = 'DeviseController' + + # ==> Mailer Configuration + # Configure the e-mail address which will be shown in Devise::Mailer, + # note that it will be overwritten if you use your own mailer class + # with default "from" parameter. + config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' + + # Configure the class responsible to send e-mails. + # config.mailer = 'Devise::Mailer' + + # Configure the parent class responsible to send e-mails. + # config.parent_mailer = 'ActionMailer::Base' + + # ==> ORM configuration + # Load and configure the ORM. Supports :active_record (default) and + # :mongoid (bson_ext recommended) by default. Other ORMs may be + # available as additional gems. + require 'devise/orm/active_record' + + # ==> Configuration for any authentication mechanism + # Configure which keys are used when authenticating a user. The default is + # just :email. You can configure it to use [:username, :subdomain], so for + # authenticating a user, both parameters are required. Remember that those + # parameters are used only when authenticating and not when retrieving from + # session. If you need permissions, you should implement that in a before filter. + # You can also supply a hash where the value is a boolean determining whether + # or not authentication should be aborted when the value is not present. + config.authentication_keys = [ :username ] + + # Configure parameters from the request object used for authentication. Each entry + # given should be a request method and it will automatically be passed to the + # find_for_authentication method and considered in your model lookup. For instance, + # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. + # The same considerations mentioned for authentication_keys also apply to request_keys. + # config.request_keys = [] + + # Configure which authentication keys should be case-insensitive. + # These keys will be downcased upon creating or modifying a user and when used + # to authenticate or find a user. Default is :email. + config.case_insensitive_keys = [:email] + + # Configure which authentication keys should have whitespace stripped. + # These keys will have whitespace before and after removed upon creating or + # modifying a user and when used to authenticate or find a user. Default is :email. + config.strip_whitespace_keys = [:email] + + # Tell if authentication through request.params is enabled. True by default. + # It can be set to an array that will enable params authentication only for the + # given strategies, for example, `config.params_authenticatable = [:database]` will + # enable it only for database (email + password) authentication. + # config.params_authenticatable = true + + # Tell if authentication through HTTP Auth is enabled. False by default. + # It can be set to an array that will enable http authentication only for the + # given strategies, for example, `config.http_authenticatable = [:database]` will + # enable it only for database authentication. + # For API-only applications to support authentication "out-of-the-box", you will likely want to + # enable this with :database unless you are using a custom strategy. + # The supported strategies are: + # :database = Support basic authentication with authentication key + password + config.http_authenticatable = true + + # If 401 status code should be returned for AJAX requests. True by default. + # config.http_authenticatable_on_xhr = true + + # The realm used in Http Basic Authentication. 'Application' by default. + # config.http_authentication_realm = 'Application' + + # It will change confirmation, password recovery and other workflows + # to behave the same regardless if the e-mail provided was right or wrong. + # Does not affect registerable. + # config.paranoid = true + + # By default Devise will store the user in session. You can skip storage for + # particular strategies by setting this option. + # Notice that if you are skipping storage for all authentication paths, you + # may want to disable generating routes to Devise's sessions controller by + # passing skip: :sessions to `devise_for` in your config/routes.rb + config.skip_session_storage = [:http_auth] + + # By default, Devise cleans up the CSRF token on authentication to + # avoid CSRF token fixation attacks. This means that, when using AJAX + # requests for sign in and sign up, you need to get a new CSRF token + # from the server. You can disable this option at your own risk. + # config.clean_up_csrf_token_on_authentication = true + + # When false, Devise will not attempt to reload routes on eager load. + # This can reduce the time taken to boot the app but if your application + # requires the Devise mappings to be loaded during boot time the application + # won't boot properly. + # config.reload_routes = true + + # ==> Configuration for :database_authenticatable + # For bcrypt, this is the cost for hashing the password and defaults to 12. If + # using other algorithms, it sets how many times you want the password to be hashed. + # The number of stretches used for generating the hashed password are stored + # with the hashed password. This allows you to change the stretches without + # invalidating existing passwords. + # + # Limiting the stretches to just one in testing will increase the performance of + # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use + # a value less than 10 in other environments. Note that, for bcrypt (the default + # algorithm), the cost increases exponentially with the number of stretches (e.g. + # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). + config.stretches = Rails.env.test? ? 1 : 12 + + # Set up a pepper to generate the hashed password. + # config.pepper = '8b94639bc3aa104aa9b17554d6209cdc5bbbd767a3296f3f6600220cda59ddae62ddc13c37250d3602924f4e4d9c0e24788e318eba5c60dff77e478139388460' + + # Send a notification to the original email when the user's email is changed. + # config.send_email_changed_notification = false + + # Send a notification email when the user's password is changed. + # config.send_password_change_notification = false + + # ==> Configuration for :confirmable + # A period that the user is allowed to access the website even without + # confirming their account. For instance, if set to 2.days, the user will be + # able to access the website for two days without confirming their account, + # access will be blocked just in the third day. + # You can also set it to nil, which will allow the user to access the website + # without confirming their account. + # Default is 0.days, meaning the user cannot access the website without + # confirming their account. + # config.allow_unconfirmed_access_for = 2.days + + # A period that the user is allowed to confirm their account before their + # token becomes invalid. For example, if set to 3.days, the user can confirm + # their account within 3 days after the mail was sent, but on the fourth day + # their account can't be confirmed with the token any more. + # Default is nil, meaning there is no restriction on how long a user can take + # before confirming their account. + # config.confirm_within = 3.days + + # If true, requires any email changes to be confirmed (exactly the same way as + # initial account confirmation) to be applied. Requires additional unconfirmed_email + # db field (see migrations). Until confirmed, new email is stored in + # unconfirmed_email column, and copied to email column on successful confirmation. + config.reconfirmable = true + + # Defines which key will be used when confirming an account + # config.confirmation_keys = [:email] + + # ==> Configuration for :rememberable + # The time the user will be remembered without asking for credentials again. + # config.remember_for = 2.weeks + + # Invalidates all the remember me tokens when the user signs out. + config.expire_all_remember_me_on_sign_out = true + + # If true, extends the user's remember period when remembered via cookie. + # config.extend_remember_period = false + + # Options to be passed to the created cookie. For instance, you can set + # secure: true in order to force SSL only cookies. + # config.rememberable_options = {} + + # ==> Configuration for :validatable + # Range for password length. + config.password_length = 4..128 + + # Email regex used to validate email formats. It simply asserts that + # one (and only one) @ exists in the given string. This is mainly + # to give user feedback and not to assert the e-mail validity. + config.email_regexp = /\A[^@\s]+@[^@\s]+\z/ + + # ==> Configuration for :timeoutable + # The time you want to timeout the user session without activity. After this + # time the user will be asked for credentials again. Default is 30 minutes. + # config.timeout_in = 30.minutes + + # ==> Configuration for :lockable + # Defines which strategy will be used to lock an account. + # :failed_attempts = Locks an account after a number of failed attempts to sign in. + # :none = No lock strategy. You should handle locking by yourself. + # config.lock_strategy = :failed_attempts + + # Defines which key will be used when locking and unlocking an account + # config.unlock_keys = [:email] + + # Defines which strategy will be used to unlock an account. + # :email = Sends an unlock link to the user email + # :time = Re-enables login after a certain amount of time (see :unlock_in below) + # :both = Enables both strategies + # :none = No unlock strategy. You should handle unlocking by yourself. + # config.unlock_strategy = :both + + # Number of authentication tries before locking an account if lock_strategy + # is failed attempts. + # config.maximum_attempts = 20 + + # Time interval to unlock the account if :time is enabled as unlock_strategy. + # config.unlock_in = 1.hour + + # Warn on the last attempt before the account is locked. + # config.last_attempt_warning = true + + # ==> Configuration for :recoverable + # + # Defines which key will be used when recovering the password for an account + # config.reset_password_keys = [:email] + + # Time interval you can reset your password with a reset password key. + # Don't put a too small interval or your users won't have the time to + # change their passwords. + config.reset_password_within = 6.hours + + # When set to false, does not sign a user in automatically after their password is + # reset. Defaults to true, so a user is signed in automatically after a reset. + # config.sign_in_after_reset_password = true + + # ==> Configuration for :encryptable + # Allow you to use another hashing or encryption algorithm besides bcrypt (default). + # You can use :sha1, :sha512 or algorithms from others authentication tools as + # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20 + # for default behavior) and :restful_authentication_sha1 (then you should set + # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper). + # + # Require the `devise-encryptable` gem when using anything other than bcrypt + # config.encryptor = :sha512 + + # ==> Scopes configuration + # Turn scoped views on. Before rendering "sessions/new", it will first check for + # "users/sessions/new". It's turned off by default because it's slower if you + # are using only default views. + # config.scoped_views = false + + # Configure the default scope given to Warden. By default it's the first + # devise role declared in your routes (usually :user). + # config.default_scope = :user + + # Set this configuration to false if you want /users/sign_out to sign out + # only the current scope. By default, Devise signs out all scopes. + # config.sign_out_all_scopes = true + + # ==> Navigation configuration + # Lists the formats that should be treated as navigational. Formats like + # :html should redirect to the sign in page when the user does not have + # access, but formats like :xml or :json, should return 401. + # + # If you have any extra navigational formats, like :iphone or :mobile, you + # should add them to the navigational formats lists. + # + # The "*/*" below is required to match Internet Explorer requests. + # config.navigational_formats = ['*/*', :html, :turbo_stream] + + # The default HTTP method used to sign out a resource. Default is :delete. + config.sign_out_via = :delete + + # ==> OmniAuth + # Add a new OmniAuth provider. Check the wiki for more information on setting + # up on your models and hooks. + # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' + + # ==> Warden configuration + # If you want to use other strategies, that are not supported by Devise, or + # change the failure app, you can configure them inside the config.warden block. + # + # config.warden do |manager| + # manager.intercept_401 = false + # manager.default_strategies(scope: :user).unshift :some_external_strategy + # end + + # ==> Mountable engine configurations + # When using Devise inside an engine, let's call it `MyEngine`, and this engine + # is mountable, there are some extra configurations to be taken into account. + # The following options are available, assuming the engine is mounted as: + # + # mount MyEngine, at: '/my_engine' + # + # The router that invoked `devise_for`, in the example above, would be: + # config.router_name = :my_engine + # + # When using OmniAuth, Devise cannot automatically set OmniAuth path, + # so you need to do it manually. For the users scope, it would be: + # config.omniauth_path_prefix = '/my_engine/users/auth' + + # ==> Hotwire/Turbo configuration + # When using Devise with Hotwire/Turbo, the http status for error responses + # and some redirects must match the following. The default in Devise for existing + # apps is `200 OK` and `302 Found respectively`, but new apps are generated with + # these new defaults that match Hotwire/Turbo behavior. + # Note: These might become the new default in future versions of Devise. + config.responder.error_status = :unprocessable_entity + config.responder.redirect_status = :see_other + + # ==> Configuration for :registerable + + # When set to false, does not sign a user in automatically after their password is + # changed. Defaults to true, so a user is signed in automatically after changing a password. + # config.sign_in_after_change_password = true +end diff --git a/utils/build/docker/ruby/rails72/config/initializers/filter_parameter_logging.rb b/utils/build/docker/ruby/rails72/config/initializers/filter_parameter_logging.rb new file mode 100644 index 00000000000..4b34a036689 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,6 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [ + :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn +] diff --git a/utils/build/docker/ruby/rails72/config/initializers/inflections.rb b/utils/build/docker/ruby/rails72/config/initializers/inflections.rb new file mode 100644 index 00000000000..3860f659ead --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, "\\1en" +# inflect.singular /^(ox)en/i, "\\1" +# inflect.irregular "person", "people" +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym "RESTful" +# end diff --git a/utils/build/docker/ruby/rails72/config/initializers/permissions_policy.rb b/utils/build/docker/ruby/rails72/config/initializers/permissions_policy.rb new file mode 100644 index 00000000000..00f64d71b03 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/initializers/permissions_policy.rb @@ -0,0 +1,11 @@ +# Define an application-wide HTTP permissions policy. For further +# information see https://developers.google.com/web/updates/2018/06/feature-policy +# +# Rails.application.config.permissions_policy do |f| +# f.camera :none +# f.gyroscope :none +# f.microphone :none +# f.usb :none +# f.fullscreen :self +# f.payment :self, "https://secure.example.com" +# end diff --git a/utils/build/docker/ruby/rails72/config/locales/en.yml b/utils/build/docker/ruby/rails72/config/locales/en.yml new file mode 100644 index 00000000000..8ca56fc74f3 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/locales/en.yml @@ -0,0 +1,33 @@ +# Files in the config/locales directory are used for internationalization +# and are automatically loaded by Rails. If you want to use locales other +# than English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t "hello" +# +# In views, this is aliased to just `t`: +# +# <%= t("hello") %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# The following keys must be escaped otherwise they will not be retrieved by +# the default I18n backend: +# +# true, false, on, off, yes, no +# +# Instead, surround them with single quotes. +# +# en: +# "true": "foo" +# +# To learn more, please read the Rails Internationalization guide +# available at https://guides.rubyonrails.org/i18n.html. + +en: + hello: "Hello world" diff --git a/utils/build/docker/ruby/rails72/config/puma.rb b/utils/build/docker/ruby/rails72/config/puma.rb new file mode 100644 index 00000000000..daaf0369998 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/puma.rb @@ -0,0 +1,43 @@ +# Puma can serve each request in a thread from an internal thread pool. +# The `threads` method setting takes two numbers: a minimum and maximum. +# Any libraries that use thread pools should be configured to match +# the maximum value specified for Puma. Default is set to 5 threads for minimum +# and maximum; this matches the default thread size of Active Record. +# +max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } +min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } +threads min_threads_count, max_threads_count + +# Specifies the `worker_timeout` threshold that Puma will use to wait before +# terminating a worker in development environments. +# +worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" + +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +# +port ENV.fetch("PORT") { 3000 } + +# Specifies the `environment` that Puma will run in. +# +environment ENV.fetch("RAILS_ENV") { "development" } + +# Specifies the `pidfile` that Puma will use. +pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } + +# Specifies the number of `workers` to boot in clustered mode. +# Workers are forked web server processes. If using threads and workers together +# the concurrency of the application would be max `threads` * `workers`. +# Workers do not work on JRuby or Windows (both of which do not support +# processes). +# +# workers ENV.fetch("WEB_CONCURRENCY") { 2 } + +# Use the `preload_app!` method when specifying a `workers` number. +# This directive tells Puma to first boot the application and load code +# before forking the application. This takes advantage of Copy On Write +# process behavior so workers use less memory. +# +# preload_app! + +# Allow puma to be restarted by `bin/rails restart` command. +plugin :tmp_restart diff --git a/utils/build/docker/ruby/rails72/config/routes.rb b/utils/build/docker/ruby/rails72/config/routes.rb new file mode 100644 index 00000000000..22c3f8c1265 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/routes.rb @@ -0,0 +1,50 @@ +Rails.application.routes.draw do + # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html + + # Defines the root path route ("/") + # root "articles#index" + + get '/' => 'system_test#root' + post '/' => 'system_test#root' + + get '/healthcheck' => 'system_test#healthcheck' + + get '/waf' => 'system_test#waf' + post '/waf' => 'system_test#waf' + get '/waf/*other' => 'system_test#waf' + post '/waf/*other' => 'system_test#waf' + + get '/kafka/produce' => 'system_test#kafka_produce' + get '/kafka/consume' => 'system_test#kafka_consume' + + get '/params/:value' => 'system_test#handle_path_params' + get '/spans' => 'system_test#generate_spans' + get '/status' => 'system_test#status' + get '/read_file' => 'system_test#read_file' + get '/make_distant_call' => 'system_test#make_distant_call' + + get '/headers' => 'system_test#test_headers' + get '/identify' => 'system_test#identify' + + get 'user_login_success_event' => 'system_test#user_login_success_event' + get 'user_login_failure_event' => 'system_test#user_login_failure_event' + get 'custom_event' => 'system_test#custom_event' + + %i[get post].each do |request_method| + send(request_method, '/tag_value/:tag_value/:status_code' => 'system_test#tag_value') + end + match '/tag_value/:tag_value/:status_code' => 'system_test#tag_value', via: :options + get '/users' => 'system_test#users' + + devise_for :users + %i[get post].each do |request_method| + # We have to provide format: false to make sure the Test_DiscoveryScan test do not break + # https://github.com/DataDog/system-tests/blob/515310b5fb1fd0792fc283c9ee134ab3803d6e7c/tests/appsec/waf/test_rules.py#L374 + # The test hits '/login.pwd' and expects a 404. + # By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists + send(request_method, '/login' => 'system_test#login', format: false) + end + + get '/requestdownstream' => 'system_test#request_downstream' + get '/returnheaders' => 'system_test#return_headers' +end diff --git a/utils/build/docker/ruby/rails72/config/storage.yml b/utils/build/docker/ruby/rails72/config/storage.yml new file mode 100644 index 00000000000..4942ab66948 --- /dev/null +++ b/utils/build/docker/ruby/rails72/config/storage.yml @@ -0,0 +1,34 @@ +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +# Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) +# amazon: +# service: S3 +# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> +# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> +# region: us-east-1 +# bucket: your_own_bucket-<%= Rails.env %> + +# Remember not to checkin your GCS keyfile to a repository +# google: +# service: GCS +# project: your_project +# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> +# bucket: your_own_bucket-<%= Rails.env %> + +# Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) +# microsoft: +# service: AzureStorage +# storage_account_name: your_account_name +# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> +# container: your_container_name-<%= Rails.env %> + +# mirror: +# service: Mirror +# primary: local +# mirrors: [ amazon, google, microsoft ] diff --git a/utils/build/docker/ruby/rails72/db/migrate/20230621141816_devise_create_users.rb b/utils/build/docker/ruby/rails72/db/migrate/20230621141816_devise_create_users.rb new file mode 100644 index 00000000000..0f43e58c82c --- /dev/null +++ b/utils/build/docker/ruby/rails72/db/migrate/20230621141816_devise_create_users.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +class DeviseCreateUsers < ActiveRecord::Migration[7.0] + def change + create_table :users, id: :string do |t| + ## Database authenticatable + t.string :username, null: false, default: "" + t.string :email, null: false, default: "" + t.string :encrypted_password, null: false, default: "" + + ## Recoverable + t.string :reset_password_token + t.datetime :reset_password_sent_at + + ## Rememberable + t.datetime :remember_created_at + + ## Trackable + # t.integer :sign_in_count, default: 0, null: false + # t.datetime :current_sign_in_at + # t.datetime :last_sign_in_at + # t.string :current_sign_in_ip + # t.string :last_sign_in_ip + + ## Confirmable + # t.string :confirmation_token + # t.datetime :confirmed_at + # t.datetime :confirmation_sent_at + # t.string :unconfirmed_email # Only if using reconfirmable + + ## Lockable + # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts + # t.string :unlock_token # Only if unlock strategy is :email or :both + # t.datetime :locked_at + + + t.timestamps null: false + end + + add_index :users, :email, unique: true + add_index :users, :reset_password_token, unique: true + # add_index :users, :confirmation_token, unique: true + # add_index :users, :unlock_token, unique: true + end +end diff --git a/utils/build/docker/ruby/rails40/db/seeds.rb b/utils/build/docker/ruby/rails72/db/seeds.rb similarity index 100% rename from utils/build/docker/ruby/rails40/db/seeds.rb rename to utils/build/docker/ruby/rails72/db/seeds.rb diff --git a/utils/build/docker/ruby/rails41/test/fixtures/.keep b/utils/build/docker/ruby/rails72/lib/assets/.keep similarity index 100% rename from utils/build/docker/ruby/rails41/test/fixtures/.keep rename to utils/build/docker/ruby/rails72/lib/assets/.keep diff --git a/utils/build/docker/ruby/rails41/test/helpers/.keep b/utils/build/docker/ruby/rails72/lib/tasks/.keep similarity index 100% rename from utils/build/docker/ruby/rails41/test/helpers/.keep rename to utils/build/docker/ruby/rails72/lib/tasks/.keep diff --git a/utils/build/docker/ruby/rails72/public/404.html b/utils/build/docker/ruby/rails72/public/404.html new file mode 100644 index 00000000000..2be3af26fc5 --- /dev/null +++ b/utils/build/docker/ruby/rails72/public/404.html @@ -0,0 +1,67 @@ + + + + The page you were looking for doesn't exist (404) + + + + + + +
+
+

The page you were looking for doesn't exist.

+

You may have mistyped the address or the page may have moved.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/utils/build/docker/ruby/rails72/public/422.html b/utils/build/docker/ruby/rails72/public/422.html new file mode 100644 index 00000000000..c08eac0d1df --- /dev/null +++ b/utils/build/docker/ruby/rails72/public/422.html @@ -0,0 +1,67 @@ + + + + The change you wanted was rejected (422) + + + + + + +
+
+

The change you wanted was rejected.

+

Maybe you tried to change something you didn't have access to.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/utils/build/docker/ruby/rails72/public/500.html b/utils/build/docker/ruby/rails72/public/500.html new file mode 100644 index 00000000000..78a030af22e --- /dev/null +++ b/utils/build/docker/ruby/rails72/public/500.html @@ -0,0 +1,66 @@ + + + + We're sorry, but something went wrong (500) + + + + + + +
+
+

We're sorry, but something went wrong.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/utils/build/docker/ruby/rails32/vendor/plugins/.gitkeep b/utils/build/docker/ruby/rails72/public/apple-touch-icon-precomposed.png similarity index 100% rename from utils/build/docker/ruby/rails32/vendor/plugins/.gitkeep rename to utils/build/docker/ruby/rails72/public/apple-touch-icon-precomposed.png diff --git a/utils/build/docker/ruby/rails41/public/favicon.ico b/utils/build/docker/ruby/rails72/public/apple-touch-icon.png similarity index 100% rename from utils/build/docker/ruby/rails41/public/favicon.ico rename to utils/build/docker/ruby/rails72/public/apple-touch-icon.png diff --git a/utils/build/docker/ruby/rails41/test/integration/.keep b/utils/build/docker/ruby/rails72/public/favicon.ico similarity index 100% rename from utils/build/docker/ruby/rails41/test/integration/.keep rename to utils/build/docker/ruby/rails72/public/favicon.ico diff --git a/utils/build/docker/ruby/rails72/public/robots.txt b/utils/build/docker/ruby/rails72/public/robots.txt new file mode 100644 index 00000000000..c19f78ab683 --- /dev/null +++ b/utils/build/docker/ruby/rails72/public/robots.txt @@ -0,0 +1 @@ +# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file diff --git a/utils/build/docker/ruby/rails41/test/mailers/.keep b/utils/build/docker/ruby/rails72/storage/.keep similarity index 100% rename from utils/build/docker/ruby/rails41/test/mailers/.keep rename to utils/build/docker/ruby/rails72/storage/.keep diff --git a/utils/build/docker/ruby/rails72/test/application_system_test_case.rb b/utils/build/docker/ruby/rails72/test/application_system_test_case.rb new file mode 100644 index 00000000000..d19212abd5c --- /dev/null +++ b/utils/build/docker/ruby/rails72/test/application_system_test_case.rb @@ -0,0 +1,5 @@ +require "test_helper" + +class ApplicationSystemTestCase < ActionDispatch::SystemTestCase + driven_by :selenium, using: :chrome, screen_size: [1400, 1400] +end diff --git a/utils/build/docker/ruby/rails72/test/channels/application_cable/connection_test.rb b/utils/build/docker/ruby/rails72/test/channels/application_cable/connection_test.rb new file mode 100644 index 00000000000..800405f15e6 --- /dev/null +++ b/utils/build/docker/ruby/rails72/test/channels/application_cable/connection_test.rb @@ -0,0 +1,11 @@ +require "test_helper" + +class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase + # test "connects with cookies" do + # cookies.signed[:user_id] = 42 + # + # connect + # + # assert_equal connection.user_id, "42" + # end +end diff --git a/utils/build/docker/ruby/rails41/test/models/.keep b/utils/build/docker/ruby/rails72/test/controllers/.keep similarity index 100% rename from utils/build/docker/ruby/rails41/test/models/.keep rename to utils/build/docker/ruby/rails72/test/controllers/.keep diff --git a/utils/build/docker/ruby/rails41/vendor/assets/javascripts/.keep b/utils/build/docker/ruby/rails72/test/fixtures/files/.keep similarity index 100% rename from utils/build/docker/ruby/rails41/vendor/assets/javascripts/.keep rename to utils/build/docker/ruby/rails72/test/fixtures/files/.keep diff --git a/utils/build/docker/ruby/rails41/vendor/assets/stylesheets/.keep b/utils/build/docker/ruby/rails72/test/helpers/.keep similarity index 100% rename from utils/build/docker/ruby/rails41/vendor/assets/stylesheets/.keep rename to utils/build/docker/ruby/rails72/test/helpers/.keep diff --git a/utils/build/docker/ruby/rails72/test/integration/.keep b/utils/build/docker/ruby/rails72/test/integration/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails72/test/mailers/.keep b/utils/build/docker/ruby/rails72/test/mailers/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails72/test/models/.keep b/utils/build/docker/ruby/rails72/test/models/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails72/test/system/.keep b/utils/build/docker/ruby/rails72/test/system/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails72/test/test_helper.rb b/utils/build/docker/ruby/rails72/test/test_helper.rb new file mode 100644 index 00000000000..d713e377c94 --- /dev/null +++ b/utils/build/docker/ruby/rails72/test/test_helper.rb @@ -0,0 +1,13 @@ +ENV["RAILS_ENV"] ||= "test" +require_relative "../config/environment" +require "rails/test_help" + +class ActiveSupport::TestCase + # Run tests in parallel with specified workers + parallelize(workers: :number_of_processors) + + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + + # Add more helper methods to be used by all tests here... +end diff --git a/utils/build/docker/ruby/rails72/tmp/.keep b/utils/build/docker/ruby/rails72/tmp/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails72/tmp/pids/.keep b/utils/build/docker/ruby/rails72/tmp/pids/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails72/tmp/storage/.keep b/utils/build/docker/ruby/rails72/tmp/storage/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails72/vendor/.keep b/utils/build/docker/ruby/rails72/vendor/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails72/vendor/javascript/.keep b/utils/build/docker/ruby/rails72/vendor/javascript/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80.Dockerfile b/utils/build/docker/ruby/rails80.Dockerfile new file mode 100644 index 00000000000..5b1d47bc7f4 --- /dev/null +++ b/utils/build/docker/ruby/rails80.Dockerfile @@ -0,0 +1,19 @@ +FROM ghcr.io/datadog/images-rb/engines/ruby:3.4 + +RUN apt-get update && apt-get install -y nodejs npm + +RUN mkdir -p /app +WORKDIR /app + +COPY utils/build/docker/ruby/rails80/ . +COPY utils/build/docker/ruby/install_ddtrace.sh binaries* /binaries/ +RUN /binaries/install_ddtrace.sh + +ENV DD_TRACE_HEADER_TAGS=user-agent +ENV RAILS_ENV=production +ENV RAILS_MASTER_KEY=9d319c57ec128e905d9e2ce5742bf2de +RUN bundle exec rails db:create db:migrate db:seed + +RUN echo "#!/bin/bash\nbundle exec puma -b tcp://0.0.0.0 -p 7777 -w 1" > app.sh +RUN chmod +x app.sh +CMD [ "./app.sh" ] diff --git a/utils/build/docker/ruby/rails80/.dockerignore b/utils/build/docker/ruby/rails80/.dockerignore new file mode 100644 index 00000000000..df27d2d07dc --- /dev/null +++ b/utils/build/docker/ruby/rails80/.dockerignore @@ -0,0 +1,4 @@ +.envrc +shell.nix +vendor/bundle +node_modules diff --git a/utils/build/docker/ruby/rails80/.gitattributes b/utils/build/docker/ruby/rails80/.gitattributes new file mode 100644 index 00000000000..31eeee0b6ac --- /dev/null +++ b/utils/build/docker/ruby/rails80/.gitattributes @@ -0,0 +1,7 @@ +# See https://git-scm.com/docs/gitattributes for more about git attribute files. + +# Mark the database schema as having been generated. +db/schema.rb linguist-generated + +# Mark any vendored files as having been vendored. +vendor/* linguist-vendored diff --git a/utils/build/docker/ruby/rails80/.gitignore b/utils/build/docker/ruby/rails80/.gitignore new file mode 100644 index 00000000000..67ca8a3bfe0 --- /dev/null +++ b/utils/build/docker/ruby/rails80/.gitignore @@ -0,0 +1,39 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile '~/.gitignore_global' + +# Ignore bundler config. +/.bundle + +# Ignore the default SQLite database. +/db/*.sqlite3 +/db/*.sqlite3-* + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore pidfiles, but keep the directory. +/tmp/pids/* +!/tmp/pids/ +!/tmp/pids/.keep + +# Ignore uploaded files in development. +/storage/* +!/storage/.keep +/tmp/storage/* +!/tmp/storage/ +!/tmp/storage/.keep + +/public/assets + +# Ignore master key for decrypting credentials and more. +/config/master.key + +.envrc +shell.nix +/vendor/bundle diff --git a/utils/build/docker/ruby/rails80/.ruby-version b/utils/build/docker/ruby/rails80/.ruby-version new file mode 100644 index 00000000000..408069ae679 --- /dev/null +++ b/utils/build/docker/ruby/rails80/.ruby-version @@ -0,0 +1 @@ +ruby-3.4.1 diff --git a/utils/build/docker/ruby/rails80/Gemfile b/utils/build/docker/ruby/rails80/Gemfile new file mode 100644 index 00000000000..35733d01036 --- /dev/null +++ b/utils/build/docker/ruby/rails80/Gemfile @@ -0,0 +1,80 @@ +source "https://rubygems.org" +git_source(:github) { |repo| "https://github.com/#{repo}.git" } + +ruby "~> 3.4.1" + +# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" +gem "rails", "~> 8.0.0" + +# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] +gem "sprockets-rails" + +# Use sqlite3 as the database for Active Record +gem "sqlite3", ">= 2.1" + +# Use the Puma web server [https://github.com/puma/puma] +gem "puma", "~> 6.0" + +# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] +gem "importmap-rails" + +# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] +gem "turbo-rails" + +# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] +gem "stimulus-rails" + +# Build JSON APIs with ease [https://github.com/rails/jbuilder] +gem "jbuilder" + +# Talk with Kafka for propagation tests +gem "rdkafka" + +# Use Redis adapter to run Action Cable in production +# gem "redis", "~> 4.0" + +# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] +# gem "kredis" + +# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] +# gem "bcrypt", "~> 3.1.7" + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ] + +# Reduces boot times through caching; required in config/boot.rb +gem "bootsnap", require: false + +# Use Sass to process CSS +# gem "sassc-rails" + +# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] +# gem "image_processing", "~> 1.2" + +group :development, :test do + # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem + gem "debug", platforms: %i[ mri mingw x64_mingw ] +end + +group :development do + # Use console on exceptions pages [https://github.com/rails/web-console] + gem "web-console" + + # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler] + # gem "rack-mini-profiler" + + # Speed up commands on slow machines / big apps [https://github.com/rails/spring] + # gem "spring" +end + +group :test do + # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] + gem "capybara" + gem "selenium-webdriver" + gem "webdrivers" +end + +gem 'devise' + +gem 'pry' +gem 'datadog', '~> 2.7.0', require: 'datadog/auto_instrument' diff --git a/utils/build/docker/ruby/rails80/Gemfile.lock b/utils/build/docker/ruby/rails80/Gemfile.lock new file mode 100644 index 00000000000..fe8dde40b86 --- /dev/null +++ b/utils/build/docker/ruby/rails80/Gemfile.lock @@ -0,0 +1,357 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (8.0.1) + actionpack (= 8.0.1) + activesupport (= 8.0.1) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + zeitwerk (~> 2.6) + actionmailbox (8.0.1) + actionpack (= 8.0.1) + activejob (= 8.0.1) + activerecord (= 8.0.1) + activestorage (= 8.0.1) + activesupport (= 8.0.1) + mail (>= 2.8.0) + actionmailer (8.0.1) + actionpack (= 8.0.1) + actionview (= 8.0.1) + activejob (= 8.0.1) + activesupport (= 8.0.1) + mail (>= 2.8.0) + rails-dom-testing (~> 2.2) + actionpack (8.0.1) + actionview (= 8.0.1) + activesupport (= 8.0.1) + nokogiri (>= 1.8.5) + rack (>= 2.2.4) + rack-session (>= 1.0.1) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + useragent (~> 0.16) + actiontext (8.0.1) + actionpack (= 8.0.1) + activerecord (= 8.0.1) + activestorage (= 8.0.1) + activesupport (= 8.0.1) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (8.0.1) + activesupport (= 8.0.1) + builder (~> 3.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (8.0.1) + activesupport (= 8.0.1) + globalid (>= 0.3.6) + activemodel (8.0.1) + activesupport (= 8.0.1) + activerecord (8.0.1) + activemodel (= 8.0.1) + activesupport (= 8.0.1) + timeout (>= 0.4.0) + activestorage (8.0.1) + actionpack (= 8.0.1) + activejob (= 8.0.1) + activerecord (= 8.0.1) + activesupport (= 8.0.1) + marcel (~> 1.0) + activesupport (8.0.1) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + base64 (0.2.0) + bcrypt (3.1.20) + benchmark (0.4.0) + bigdecimal (3.1.9) + bindex (0.8.1) + bootsnap (1.18.4) + msgpack (~> 1.2) + builder (3.3.0) + capybara (3.40.0) + addressable + matrix + mini_mime (>= 0.1.3) + nokogiri (~> 1.11) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (>= 1.5, < 3.0) + xpath (~> 3.2) + coderay (1.1.3) + concurrent-ruby (1.3.4) + connection_pool (2.4.1) + crass (1.0.6) + datadog (2.7.1) + datadog-ruby_core_source (~> 3.3) + libdatadog (~> 14.1.0.1.0) + libddwaf (~> 1.15.0.0.0) + msgpack + datadog-ruby_core_source (3.3.7) + date (3.4.1) + debug (1.10.0) + irb (~> 1.10) + reline (>= 0.3.8) + devise (4.9.4) + bcrypt (~> 3.0) + orm_adapter (~> 0.1) + railties (>= 4.1.0) + responders + warden (~> 1.2.3) + drb (2.2.1) + erubi (1.13.1) + ffi (1.17.1) + ffi (1.17.1-aarch64-linux-gnu) + ffi (1.17.1-aarch64-linux-musl) + ffi (1.17.1-arm-linux-gnu) + ffi (1.17.1-arm-linux-musl) + ffi (1.17.1-arm64-darwin) + ffi (1.17.1-x86-linux-gnu) + ffi (1.17.1-x86-linux-musl) + ffi (1.17.1-x86_64-darwin) + ffi (1.17.1-x86_64-linux-gnu) + ffi (1.17.1-x86_64-linux-musl) + globalid (1.2.1) + activesupport (>= 6.1) + i18n (1.14.6) + concurrent-ruby (~> 1.0) + importmap-rails (2.1.0) + actionpack (>= 6.0.0) + activesupport (>= 6.0.0) + railties (>= 6.0.0) + io-console (0.8.0) + irb (1.14.3) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + jbuilder (2.13.0) + actionview (>= 5.0.0) + activesupport (>= 5.0.0) + libdatadog (14.1.0.1.0) + libdatadog (14.1.0.1.0-aarch64-linux) + libdatadog (14.1.0.1.0-x86_64-linux) + libddwaf (1.15.0.0.0) + ffi (~> 1.0) + libddwaf (1.15.0.0.0-aarch64-linux) + ffi (~> 1.0) + libddwaf (1.15.0.0.0-arm64-darwin) + ffi (~> 1.0) + libddwaf (1.15.0.0.0-x86_64-darwin) + ffi (~> 1.0) + libddwaf (1.15.0.0.0-x86_64-linux) + ffi (~> 1.0) + logger (1.6.4) + loofah (2.24.0) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + mail (2.8.1) + mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp + marcel (1.0.4) + matrix (0.4.2) + method_source (1.1.0) + mini_mime (1.1.5) + mini_portile2 (2.8.8) + minitest (5.25.4) + msgpack (1.7.5) + net-imap (0.5.4) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-smtp (0.5.0) + net-protocol + nio4r (2.7.4) + nokogiri (1.18.1) + mini_portile2 (~> 2.8.2) + racc (~> 1.4) + nokogiri (1.18.1-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.1-aarch64-linux-musl) + racc (~> 1.4) + nokogiri (1.18.1-arm-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.1-arm-linux-musl) + racc (~> 1.4) + nokogiri (1.18.1-arm64-darwin) + racc (~> 1.4) + nokogiri (1.18.1-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.18.1-x86_64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.1-x86_64-linux-musl) + racc (~> 1.4) + orm_adapter (0.5.0) + pry (0.15.2) + coderay (~> 1.1) + method_source (~> 1.0) + psych (5.2.2) + date + stringio + public_suffix (6.0.1) + puma (6.5.0) + nio4r (~> 2.0) + racc (1.8.1) + rack (3.1.8) + rack-session (2.0.0) + rack (>= 3.0.0) + rack-test (2.2.0) + rack (>= 1.3) + rackup (2.2.1) + rack (>= 3) + rails (8.0.1) + actioncable (= 8.0.1) + actionmailbox (= 8.0.1) + actionmailer (= 8.0.1) + actionpack (= 8.0.1) + actiontext (= 8.0.1) + actionview (= 8.0.1) + activejob (= 8.0.1) + activemodel (= 8.0.1) + activerecord (= 8.0.1) + activestorage (= 8.0.1) + activesupport (= 8.0.1) + bundler (>= 1.15.0) + railties (= 8.0.1) + rails-dom-testing (2.2.0) + activesupport (>= 5.0.0) + minitest + nokogiri (>= 1.6) + rails-html-sanitizer (1.6.2) + loofah (~> 2.21) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + railties (8.0.1) + actionpack (= 8.0.1) + activesupport (= 8.0.1) + irb (~> 1.13) + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + rake (13.2.1) + rdkafka (0.19.0) + ffi (~> 1.15) + mini_portile2 (~> 2.6) + rake (> 12) + rdoc (6.10.0) + psych (>= 4.0.0) + regexp_parser (2.10.0) + reline (0.6.0) + io-console (~> 0.5) + responders (3.1.1) + actionpack (>= 5.2) + railties (>= 5.2) + rexml (3.4.0) + rubyzip (2.3.2) + securerandom (0.4.1) + selenium-webdriver (4.10.0) + rexml (~> 3.2, >= 3.2.5) + rubyzip (>= 1.2.2, < 3.0) + websocket (~> 1.0) + sprockets (4.2.1) + concurrent-ruby (~> 1.0) + rack (>= 2.2.4, < 4) + sprockets-rails (3.5.2) + actionpack (>= 6.1) + activesupport (>= 6.1) + sprockets (>= 3.0.0) + sqlite3 (2.5.0) + mini_portile2 (~> 2.8.0) + sqlite3 (2.5.0-aarch64-linux-gnu) + sqlite3 (2.5.0-aarch64-linux-musl) + sqlite3 (2.5.0-arm-linux-gnu) + sqlite3 (2.5.0-arm-linux-musl) + sqlite3 (2.5.0-arm64-darwin) + sqlite3 (2.5.0-x86-linux-gnu) + sqlite3 (2.5.0-x86-linux-musl) + sqlite3 (2.5.0-x86_64-darwin) + sqlite3 (2.5.0-x86_64-linux-gnu) + sqlite3 (2.5.0-x86_64-linux-musl) + stimulus-rails (1.3.4) + railties (>= 6.0.0) + stringio (3.1.2) + thor (1.3.2) + timeout (0.4.3) + turbo-rails (2.0.11) + actionpack (>= 6.0.0) + railties (>= 6.0.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + uri (1.0.2) + useragent (0.16.11) + warden (1.2.9) + rack (>= 2.0.9) + web-console (4.2.1) + actionview (>= 6.0.0) + activemodel (>= 6.0.0) + bindex (>= 0.4.0) + railties (>= 6.0.0) + webdrivers (5.3.1) + nokogiri (~> 1.6) + rubyzip (>= 1.3.0) + selenium-webdriver (~> 4.0, < 4.11) + websocket (1.2.11) + websocket-driver (0.7.6) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + xpath (3.2.0) + nokogiri (~> 1.8) + zeitwerk (2.7.1) + +PLATFORMS + aarch64-linux + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + arm64-darwin + ruby + x86-linux-gnu + x86-linux-musl + x86_64-darwin + x86_64-linux + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + bootsnap + capybara + datadog (~> 2.7.0) + debug + devise + importmap-rails + jbuilder + pry + puma (~> 6.0) + rails (~> 8.0.0) + rdkafka + selenium-webdriver + sprockets-rails + sqlite3 (>= 2.1) + stimulus-rails + turbo-rails + tzinfo-data + web-console + webdrivers + +RUBY VERSION + ruby 3.4.1p0 + +BUNDLED WITH + 2.6.2 diff --git a/utils/build/docker/ruby/rails80/README.md b/utils/build/docker/ruby/rails80/README.md new file mode 100644 index 00000000000..7db80e4ca1b --- /dev/null +++ b/utils/build/docker/ruby/rails80/README.md @@ -0,0 +1,24 @@ +# README + +This README would normally document whatever steps are necessary to get the +application up and running. + +Things you may want to cover: + +* Ruby version + +* System dependencies + +* Configuration + +* Database creation + +* Database initialization + +* How to run the test suite + +* Services (job queues, cache servers, search engines, etc.) + +* Deployment instructions + +* ... diff --git a/utils/build/docker/ruby/rails80/Rakefile b/utils/build/docker/ruby/rails80/Rakefile new file mode 100644 index 00000000000..9a5ea7383aa --- /dev/null +++ b/utils/build/docker/ruby/rails80/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require_relative "config/application" + +Rails.application.load_tasks diff --git a/utils/build/docker/ruby/rails80/app/assets/config/manifest.js b/utils/build/docker/ruby/rails80/app/assets/config/manifest.js new file mode 100644 index 00000000000..ddd546a0be4 --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/assets/config/manifest.js @@ -0,0 +1,4 @@ +//= link_tree ../images +//= link_directory ../stylesheets .css +//= link_tree ../../javascript .js +//= link_tree ../../../vendor/javascript .js diff --git a/utils/build/docker/ruby/rails80/app/assets/images/.keep b/utils/build/docker/ruby/rails80/app/assets/images/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/app/assets/stylesheets/application.css b/utils/build/docker/ruby/rails80/app/assets/stylesheets/application.css new file mode 100644 index 00000000000..288b9ab7182 --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/assets/stylesheets/application.css @@ -0,0 +1,15 @@ +/* + * This is a manifest file that'll be compiled into application.css, which will include all the files + * listed below. + * + * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's + * vendor/assets/stylesheets directory can be referenced here using a relative path. + * + * You're free to add application-wide styles to this file and they'll appear at the bottom of the + * compiled file so the styles you add here take precedence over styles defined in any other CSS + * files in this directory. Styles in this file should be added after the last require_* statement. + * It is generally better to create a new file per style scope. + * + *= require_tree . + *= require_self + */ diff --git a/utils/build/docker/ruby/rails80/app/channels/application_cable/channel.rb b/utils/build/docker/ruby/rails80/app/channels/application_cable/channel.rb new file mode 100644 index 00000000000..d6726972830 --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/channels/application_cable/channel.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Channel < ActionCable::Channel::Base + end +end diff --git a/utils/build/docker/ruby/rails80/app/channels/application_cable/connection.rb b/utils/build/docker/ruby/rails80/app/channels/application_cable/connection.rb new file mode 100644 index 00000000000..0ff5442f476 --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/channels/application_cable/connection.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Connection < ActionCable::Connection::Base + end +end diff --git a/utils/build/docker/ruby/rails80/app/controllers/application_controller.rb b/utils/build/docker/ruby/rails80/app/controllers/application_controller.rb new file mode 100644 index 00000000000..09705d12ab4 --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/controllers/application_controller.rb @@ -0,0 +1,2 @@ +class ApplicationController < ActionController::Base +end diff --git a/utils/build/docker/ruby/rails80/app/controllers/concerns/.keep b/utils/build/docker/ruby/rails80/app/controllers/concerns/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/app/controllers/system_test_controller.rb b/utils/build/docker/ruby/rails80/app/controllers/system_test_controller.rb new file mode 100644 index 00000000000..ce0f1331bb2 --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/controllers/system_test_controller.rb @@ -0,0 +1,274 @@ +require 'json' + +require 'datadog/kit/appsec/events' +require 'rdkafka' + +class SystemTestController < ApplicationController + skip_before_action :verify_authenticity_token + + def root + render plain: 'Hello, world!' + end + + def healthcheck + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + render json: { + status: 'ok', + library: { + language: 'ruby', + version: version + } + } + end + + def waf + render plain: 'Hello, world!' + end + + def handle_path_params + render plain: 'Hello, world!' + end + + def generate_spans + begin + repeats = Integer(request.params['repeats'] || 0) + garbage = Integer(request.params['garbage'] || 0) + rescue ArgumentError + render plain: 'bad request', status: 400 + else + repeats.times do |i| + Datadog::Tracing.trace('repeat-#{i}') do |span| + garbage.times do |j| + span.set_tag("garbage-#{j}", "#{j}") + end + end + end + end + + render plain: 'Generated #{repeats} spans with #{garbage} garbage tags' + end + + def test_headers + response.set_header('Content-Type', 'text/plain') + response.set_header('Content-Length', '15') + response.set_header('Content-Language', 'en-US') + + render plain: 'Hello, headers!' + end + + def identify + trace = Datadog::Tracing.active_trace + trace.set_tag('usr.id', 'usr.id') + trace.set_tag('usr.name', 'usr.name') + trace.set_tag('usr.email', 'usr.email') + trace.set_tag('usr.session_id', 'usr.session_id') + trace.set_tag('usr.role', 'usr.role') + trace.set_tag('usr.scope', 'usr.scope') + + render plain: 'Hello, world!' + end + + def status + render plain: "Ok", status: params[:code] + end + + def read_file + render plain: File.read(params[:file]) + end + + def make_distant_call + url = params[:url] + uri = URI(url) + request = nil + response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + request = Net::HTTP::Get.new(uri) + + response = http.request(request) + end + + result = { + "url": url, + "status_code": response.code, + "request_headers": request.each_header.to_h, + "response_headers": response.each_header.to_h, + } + + render json: result + end + + def user_login_success_event + Datadog::Kit::AppSec::Events.track_login_success( + Datadog::Tracing.active_trace, user: {id: 'system_tests_user'}, metadata0: "value0", metadata1: "value1" + ) + + render plain: 'Hello, world!' + end + + def user_login_failure_event + Datadog::Kit::AppSec::Events.track_login_failure( + Datadog::Tracing.active_trace, user_id: 'system_tests_user', user_exists: true, metadata0: "value0", metadata1: "value1" + ) + + render plain: 'Hello, world!' + end + + def custom_event + Datadog::Kit::AppSec::Events.track('system_tests_event', Datadog::Tracing.active_trace, metadata0: "value0", metadata1: "value1") + + render plain: 'Hello, world!' + end + + def tag_value + event_value = params[:tag_value] + status_code = params[:status_code] + + if request.method == "POST" && event_value.include?('payload_in_response_body') + render json: { payload: request.POST } + return + end + + headers = request.query_string.split('&').map {|e | e.split('=')} || [] + + trace = Datadog::Tracing.active_trace + trace.set_tag("appsec.events.system_tests_appsec_event.value", event_value) + + headers.each do |key, value| + response.set_header(key, value) + end + + render plain: 'Value tagged', status: status_code + end + + def users + user_id = request.params["user"] + + Datadog::Kit::Identity.set_user(id: user_id) + + render plain: 'Hello, user!' + end + + def login + request.env["devise.allow_params_authentication"] = true + + sdk_event = request.params[:sdk_event] + sdk_user = request.params[:sdk_user] + sdk_email = request.params[:sdk_mail] + sdk_exists = request.params[:sdk_user_exists] + + if sdk_exists + sdk_exists = sdk_exists == "true" + end + + result = request.env['warden'].authenticate({ scope: Devise.mappings[:user].name }) + + if sdk_event === 'failure' && sdk_user + metadata = {} + metadata[:email] = sdk_email if sdk_email + Datadog::Kit::AppSec::Events.track_login_failure(user_id: sdk_user, user_exists: sdk_exists, **metadata) + elsif sdk_event === 'success' && sdk_user + user = {} + user[:id] = sdk_user + user[:email] = sdk_email if sdk_email + Datadog::Kit::AppSec::Events.track_login_success(user: user) + end + + unless result + render plain: '', status: 401 + return + end + + + render plain: 'Hello, world!' + end + + + def kafka_produce + config = { + :"bootstrap.servers" => "kafka:9092", + :"client.id" => "system-tests-client-producer", + :"group.id" => "system-tests-group", + } + topic = request.params["topic"] + producer = Rdkafka::Config.new(config).producer + stop = false + while stop == false + delivery_handles = [] + begin + Datadog::Tracing.trace('kafka_produce') do |span| + delivery_handles << producer.produce( + topic: topic, + payload: "Hello, world!", + ) + # This has to be done manually for now, because ruby does not add the topic + # to the span at all + span.set_tag("span.kind", "producer") + span.set_tag("kafka.topic", topic) + stop = true + end + rescue Rdkafka::BaseError + end + delivery_handles.each(&:wait) + end + producer.close + + render plain: "Done" + end + + + def kafka_consume + config = { + :"bootstrap.servers" => "kafka:9092", + :"client.id" => "system-tests-client-consumer", + :"group.id" => "system-tests-group", + :"auto.offset.reset" => "earliest", + } + topic = request.params["topic"] + consumer = Rdkafka::Config.new(config).consumer + consumer.subscribe(topic) + begin + consumer.each do |message| + if not message.nil? + Datadog::Tracing.trace('kafka_consume') do |span| + span.set_tag("span.kind", "consumer") + span.set_tag("kafka.topic", topic) + end + break + end + end + rescue Exception => e + puts "An error has occurred while consuming messages from Kafka: #{e}" + ensure + consumer.close + end + + render plain: "Done" + end + + def request_downstream + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + render json: ext_response.body, content_type: 'application/json' + end + + def return_headers + request_headers = request.headers.each.to_h.select do |k, _v| + k.start_with?('HTTP_') || k == 'CONTENT_TYPE' || k == 'CONTENT_LENGTH' + end + request_headers = request_headers.transform_keys do |k| + k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') + end + render json: JSON.generate(request_headers), content_type: 'application/json' + end +end diff --git a/utils/build/docker/ruby/rails41/app/helpers/application_helper.rb b/utils/build/docker/ruby/rails80/app/helpers/application_helper.rb similarity index 100% rename from utils/build/docker/ruby/rails41/app/helpers/application_helper.rb rename to utils/build/docker/ruby/rails80/app/helpers/application_helper.rb diff --git a/utils/build/docker/ruby/rails80/app/javascript/application.js b/utils/build/docker/ruby/rails80/app/javascript/application.js new file mode 100644 index 00000000000..0d7b49404c3 --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/javascript/application.js @@ -0,0 +1,3 @@ +// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails +import "@hotwired/turbo-rails" +import "controllers" diff --git a/utils/build/docker/ruby/rails80/app/javascript/controllers/application.js b/utils/build/docker/ruby/rails80/app/javascript/controllers/application.js new file mode 100644 index 00000000000..1213e85c7ac --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/javascript/controllers/application.js @@ -0,0 +1,9 @@ +import { Application } from "@hotwired/stimulus" + +const application = Application.start() + +// Configure Stimulus development experience +application.debug = false +window.Stimulus = application + +export { application } diff --git a/utils/build/docker/ruby/rails80/app/javascript/controllers/hello_controller.js b/utils/build/docker/ruby/rails80/app/javascript/controllers/hello_controller.js new file mode 100644 index 00000000000..5975c0789d7 --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/javascript/controllers/hello_controller.js @@ -0,0 +1,7 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + connect() { + this.element.textContent = "Hello World!" + } +} diff --git a/utils/build/docker/ruby/rails80/app/javascript/controllers/index.js b/utils/build/docker/ruby/rails80/app/javascript/controllers/index.js new file mode 100644 index 00000000000..54ad4cad4d4 --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/javascript/controllers/index.js @@ -0,0 +1,11 @@ +// Import and register all your controllers from the importmap under controllers/* + +import { application } from "controllers/application" + +// Eager load all controllers defined in the import map under controllers/**/*_controller +import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading" +eagerLoadControllersFrom("controllers", application) + +// Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!) +// import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading" +// lazyLoadControllersFrom("controllers", application) diff --git a/utils/build/docker/ruby/rails80/app/jobs/application_job.rb b/utils/build/docker/ruby/rails80/app/jobs/application_job.rb new file mode 100644 index 00000000000..d394c3d1062 --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/jobs/application_job.rb @@ -0,0 +1,7 @@ +class ApplicationJob < ActiveJob::Base + # Automatically retry jobs that encountered a deadlock + # retry_on ActiveRecord::Deadlocked + + # Most jobs are safe to ignore if the underlying records are no longer available + # discard_on ActiveJob::DeserializationError +end diff --git a/utils/build/docker/ruby/rails80/app/mailers/application_mailer.rb b/utils/build/docker/ruby/rails80/app/mailers/application_mailer.rb new file mode 100644 index 00000000000..3c34c8148f1 --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: "from@example.com" + layout "mailer" +end diff --git a/utils/build/docker/ruby/rails80/app/models/application_record.rb b/utils/build/docker/ruby/rails80/app/models/application_record.rb new file mode 100644 index 00000000000..b63caeb8a5c --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + primary_abstract_class +end diff --git a/utils/build/docker/ruby/rails80/app/models/concerns/.keep b/utils/build/docker/ruby/rails80/app/models/concerns/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/app/models/user.rb b/utils/build/docker/ruby/rails80/app/models/user.rb new file mode 100644 index 00000000000..47567994e9c --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/models/user.rb @@ -0,0 +1,6 @@ +class User < ApplicationRecord + # Include default devise modules. Others available are: + # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable + devise :database_authenticatable, :registerable, + :recoverable, :rememberable, :validatable +end diff --git a/utils/build/docker/ruby/rails80/app/views/layouts/application.html.erb b/utils/build/docker/ruby/rails80/app/views/layouts/application.html.erb new file mode 100644 index 00000000000..0d2f3c9bdb9 --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/views/layouts/application.html.erb @@ -0,0 +1,16 @@ + + + + Rails70 + + <%= csrf_meta_tags %> + <%= csp_meta_tag %> + + <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> + <%= javascript_importmap_tags %> + + + + <%= yield %> + + diff --git a/utils/build/docker/ruby/rails80/app/views/layouts/mailer.html.erb b/utils/build/docker/ruby/rails80/app/views/layouts/mailer.html.erb new file mode 100644 index 00000000000..cbd34d2e9dd --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/views/layouts/mailer.html.erb @@ -0,0 +1,13 @@ + + + + + + + + + <%= yield %> + + diff --git a/utils/build/docker/ruby/rails80/app/views/layouts/mailer.text.erb b/utils/build/docker/ruby/rails80/app/views/layouts/mailer.text.erb new file mode 100644 index 00000000000..37f0bddbd74 --- /dev/null +++ b/utils/build/docker/ruby/rails80/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/utils/build/docker/ruby/rails80/bin/rails b/utils/build/docker/ruby/rails80/bin/rails new file mode 100755 index 00000000000..efc0377492f --- /dev/null +++ b/utils/build/docker/ruby/rails80/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path("../config/application", __dir__) +require_relative "../config/boot" +require "rails/commands" diff --git a/utils/build/docker/ruby/rails80/config.ru b/utils/build/docker/ruby/rails80/config.ru new file mode 100644 index 00000000000..4a3c09a6889 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config.ru @@ -0,0 +1,6 @@ +# This file is used by Rack-based servers to start the application. + +require_relative "config/environment" + +run Rails.application +Rails.application.load_server diff --git a/utils/build/docker/ruby/rails80/config/application.rb b/utils/build/docker/ruby/rails80/config/application.rb new file mode 100644 index 00000000000..1f0390ac072 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/application.rb @@ -0,0 +1,22 @@ +require_relative "boot" + +require "rails/all" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module Rails70 + class Application < Rails::Application + # Initialize configuration defaults for originally generated Rails version. + config.load_defaults 7.0 + + # Configuration for the application, engines, and railties goes here. + # + # These settings can be overridden in specific environments using the files + # in config/environments, which are processed later. + # + # config.time_zone = "Central Time (US & Canada)" + # config.eager_load_paths << Rails.root.join("extras") + end +end diff --git a/utils/build/docker/ruby/rails80/config/boot.rb b/utils/build/docker/ruby/rails80/config/boot.rb new file mode 100644 index 00000000000..988a5ddc460 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/boot.rb @@ -0,0 +1,4 @@ +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +require "bundler/setup" # Set up gems listed in the Gemfile. +require "bootsnap/setup" # Speed up boot time by caching expensive operations. diff --git a/utils/build/docker/ruby/rails80/config/cable.yml b/utils/build/docker/ruby/rails80/config/cable.yml new file mode 100644 index 00000000000..8ea8617f58f --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/cable.yml @@ -0,0 +1,10 @@ +development: + adapter: async + +test: + adapter: test + +production: + adapter: redis + url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> + channel_prefix: rails70_production diff --git a/utils/build/docker/ruby/rails80/config/credentials.yml.enc b/utils/build/docker/ruby/rails80/config/credentials.yml.enc new file mode 100644 index 00000000000..aeb5eb19e65 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/credentials.yml.enc @@ -0,0 +1 @@ +G5RovwV49vRCRsWk/HDncp0URlHKknKKjpxxP5znIc/TKR+dvGVoevXlv7QrfaJG1X8gq4nnL1uahrEwFNtqc5qVrTeM/GrFoY5UUthoIjDNTG8CboZEpCfvlo5n7qC1Tm3SnkxCR4q0c1Hpq7GFkRnpPRhK/Y69Xd/2TyHirAHGKPfWb27aS77VXtFO7Haho9NnL3mB5PPn1VEIQnwBAhRggeQF6hs460e6tS5nZiKsa3QOO1G86Q1sU7k3AF/J+cG/NIT555LI3Wso7qU80KySor4j/IY+DVe7jys8XB9frX5ppt2vfnRc/F5indCRUrT7N8wXdLx7C1eOxyWNLKt2L9fmt1JYauOlI/GZ9YJWtqqAkPDsssYuUc8F6ZeIZQQTxHWeFd4MJZVplFKDrG20lUROIAz41nAM--qxpsBmnjgm5xqiYc--Dow+e/9K97oMj5VdQge/tQ== \ No newline at end of file diff --git a/utils/build/docker/ruby/rails80/config/database.yml b/utils/build/docker/ruby/rails80/config/database.yml new file mode 100644 index 00000000000..fcba57f19f0 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/database.yml @@ -0,0 +1,25 @@ +# SQLite. Versions 3.8.0 and up are supported. +# gem install sqlite3 +# +# Ensure the SQLite 3 gem is defined in your Gemfile +# gem "sqlite3" +# +default: &default + adapter: sqlite3 + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + timeout: 5000 + +development: + <<: *default + database: db/development.sqlite3 + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: db/test.sqlite3 + +production: + <<: *default + database: db/production.sqlite3 diff --git a/utils/build/docker/ruby/rails80/config/environment.rb b/utils/build/docker/ruby/rails80/config/environment.rb new file mode 100644 index 00000000000..cac53157752 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require_relative "application" + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/utils/build/docker/ruby/rails80/config/environments/development.rb b/utils/build/docker/ruby/rails80/config/environments/development.rb new file mode 100644 index 00000000000..5e311ae21d2 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/environments/development.rb @@ -0,0 +1,72 @@ +require "active_support/core_ext/integer/time" + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded any time + # it changes. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports. + config.consider_all_requests_local = true + + # Enable server timing + config.server_timing = true + + # Enable/disable caching. By default caching is disabled. + # Run rails dev:cache to toggle caching. + if Rails.root.join("tmp/caching-dev.txt").exist? + config.action_controller.perform_caching = true + config.action_controller.enable_fragment_cache_logging = true + + config.cache_store = :memory_store + config.public_file_server.headers = { + "Cache-Control" => "public, max-age=#{2.days.to_i}" + } + else + config.action_controller.perform_caching = false + + config.cache_store = :null_store + end + + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = :local + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + config.action_mailer.perform_caching = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + + # Suppress logger output for asset requests. + config.assets.quiet = true + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true + + # Uncomment if you wish to allow Action Cable access from any origin. + # config.action_cable.disable_request_forgery_protection = true + + config.hosts.clear +end diff --git a/utils/build/docker/ruby/rails80/config/environments/production.rb b/utils/build/docker/ruby/rails80/config/environments/production.rb new file mode 100644 index 00000000000..e58961b3138 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/environments/production.rb @@ -0,0 +1,93 @@ +require "active_support/core_ext/integer/time" + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] + # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # config.require_master_key = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? + + # Compress CSS using a preprocessor. + # config.assets.css_compressor = :sass + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = false + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.asset_host = "http://assets.example.com" + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache + # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX + + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = :local + + # Mount Action Cable outside main process or domain. + # config.action_cable.mount_path = nil + # config.action_cable.url = "wss://example.com/cable" + # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Include generic and useful information about system operation, but avoid logging too much + # information to avoid inadvertent exposure of personally identifiable information (PII). + config.log_level = :info + + # Prepend all log lines with the following tags. + config.log_tags = [ :request_id ] + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Use a real queuing backend for Active Job (and separate queues per environment). + # config.active_job.queue_adapter = :resque + # config.active_job.queue_name_prefix = "rails70_production" + + config.action_mailer.perform_caching = false + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Don't log any deprecations. + config.active_support.report_deprecations = false + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Use a different logger for distributed setups. + # require "syslog/logger" + # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new "app-name") + + if ENV["RAILS_LOG_TO_STDOUT"].present? + logger = ActiveSupport::Logger.new(STDOUT) + logger.formatter = config.log_formatter + config.logger = ActiveSupport::TaggedLogging.new(logger) + end + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false +end diff --git a/utils/build/docker/ruby/rails80/config/environments/test.rb b/utils/build/docker/ruby/rails80/config/environments/test.rb new file mode 100644 index 00000000000..6ea4d1e7063 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/environments/test.rb @@ -0,0 +1,60 @@ +require "active_support/core_ext/integer/time" + +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Turn false under Spring and add config.action_view.cache_template_loading = true. + config.cache_classes = true + + # Eager loading loads your whole application. When running a single test locally, + # this probably isn't necessary. It's a good idea to do in a continuous integration + # system, or in some way before deploying your code. + config.eager_load = ENV["CI"].present? + + # Configure public file server for tests with Cache-Control for performance. + config.public_file_server.enabled = true + config.public_file_server.headers = { + "Cache-Control" => "public, max-age=#{1.hour.to_i}" + } + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + config.cache_store = :null_store + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Store uploaded files on the local file system in a temporary directory. + config.active_storage.service = :test + + config.action_mailer.perform_caching = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true +end diff --git a/utils/build/docker/ruby/rails80/config/importmap.rb b/utils/build/docker/ruby/rails80/config/importmap.rb new file mode 100644 index 00000000000..8dce42d4060 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/importmap.rb @@ -0,0 +1,7 @@ +# Pin npm packages by running ./bin/importmap + +pin "application", preload: true +pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true +pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true +pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true +pin_all_from "app/javascript/controllers", under: "controllers" diff --git a/utils/build/docker/ruby/rails80/config/initializers/assets.rb b/utils/build/docker/ruby/rails80/config/initializers/assets.rb new file mode 100644 index 00000000000..2eeef966fe8 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/initializers/assets.rb @@ -0,0 +1,12 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = "1.0" + +# Add additional assets to the asset load path. +# Rails.application.config.assets.paths << Emoji.images_path + +# Precompile additional assets. +# application.js, application.css, and all non-JS/CSS in the app/assets +# folder are already added. +# Rails.application.config.assets.precompile += %w( admin.js admin.css ) diff --git a/utils/build/docker/ruby/rails80/config/initializers/content_security_policy.rb b/utils/build/docker/ruby/rails80/config/initializers/content_security_policy.rb new file mode 100644 index 00000000000..3621f97f8e9 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/initializers/content_security_policy.rb @@ -0,0 +1,26 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide content security policy +# For further information see the following documentation +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy + +# Rails.application.configure do +# config.content_security_policy do |policy| +# policy.default_src :self, :https +# policy.font_src :self, :https, :data +# policy.img_src :self, :https, :data +# policy.object_src :none +# policy.script_src :self, :https +# policy.style_src :self, :https +# # Specify URI for violation reports +# # policy.report_uri "/csp-violation-report-endpoint" +# end +# +# # Generate session nonces for permitted importmap and inline scripts +# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } +# config.content_security_policy_nonce_directives = %w(script-src) +# +# # Report CSP violations to a specified URI. See: +# # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only +# # config.content_security_policy_report_only = true +# end diff --git a/utils/build/docker/ruby/rails40/config/initializers/datadog.rb b/utils/build/docker/ruby/rails80/config/initializers/datadog.rb similarity index 100% rename from utils/build/docker/ruby/rails40/config/initializers/datadog.rb rename to utils/build/docker/ruby/rails80/config/initializers/datadog.rb diff --git a/utils/build/docker/ruby/rails80/config/initializers/devise.rb b/utils/build/docker/ruby/rails80/config/initializers/devise.rb new file mode 100644 index 00000000000..098e4a0aa67 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/initializers/devise.rb @@ -0,0 +1,313 @@ +# frozen_string_literal: true + +# Assuming you have not yet modified this file, each configuration option below +# is set to its default value. Note that some are commented out while others +# are not: uncommented lines are intended to protect your configuration from +# breaking changes in upgrades (i.e., in the event that future versions of +# Devise change the default values for those options). +# +# Use this hook to configure devise mailer, warden hooks and so forth. +# Many of these configuration options can be set straight in your model. +Devise.setup do |config| + # The secret key used by Devise. Devise uses this key to generate + # random tokens. Changing this key will render invalid all existing + # confirmation, reset password and unlock tokens in the database. + # Devise will use the `secret_key_base` as its `secret_key` + # by default. You can change it below and use your own secret key. + # config.secret_key = '2aa7763a03b8aeefb5507ab110519240bbd9c017f8c15c8e5d652871ebdc194735d7acda52f0a3eef7a46fb2f16bc4a0eeacd1542a3f63ad6d56e38a15484fa8' + + # ==> Controller configuration + # Configure the parent class to the devise controllers. + # config.parent_controller = 'DeviseController' + + # ==> Mailer Configuration + # Configure the e-mail address which will be shown in Devise::Mailer, + # note that it will be overwritten if you use your own mailer class + # with default "from" parameter. + config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' + + # Configure the class responsible to send e-mails. + # config.mailer = 'Devise::Mailer' + + # Configure the parent class responsible to send e-mails. + # config.parent_mailer = 'ActionMailer::Base' + + # ==> ORM configuration + # Load and configure the ORM. Supports :active_record (default) and + # :mongoid (bson_ext recommended) by default. Other ORMs may be + # available as additional gems. + require 'devise/orm/active_record' + + # ==> Configuration for any authentication mechanism + # Configure which keys are used when authenticating a user. The default is + # just :email. You can configure it to use [:username, :subdomain], so for + # authenticating a user, both parameters are required. Remember that those + # parameters are used only when authenticating and not when retrieving from + # session. If you need permissions, you should implement that in a before filter. + # You can also supply a hash where the value is a boolean determining whether + # or not authentication should be aborted when the value is not present. + config.authentication_keys = [ :username ] + + # Configure parameters from the request object used for authentication. Each entry + # given should be a request method and it will automatically be passed to the + # find_for_authentication method and considered in your model lookup. For instance, + # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. + # The same considerations mentioned for authentication_keys also apply to request_keys. + # config.request_keys = [] + + # Configure which authentication keys should be case-insensitive. + # These keys will be downcased upon creating or modifying a user and when used + # to authenticate or find a user. Default is :email. + config.case_insensitive_keys = [:email] + + # Configure which authentication keys should have whitespace stripped. + # These keys will have whitespace before and after removed upon creating or + # modifying a user and when used to authenticate or find a user. Default is :email. + config.strip_whitespace_keys = [:email] + + # Tell if authentication through request.params is enabled. True by default. + # It can be set to an array that will enable params authentication only for the + # given strategies, for example, `config.params_authenticatable = [:database]` will + # enable it only for database (email + password) authentication. + # config.params_authenticatable = true + + # Tell if authentication through HTTP Auth is enabled. False by default. + # It can be set to an array that will enable http authentication only for the + # given strategies, for example, `config.http_authenticatable = [:database]` will + # enable it only for database authentication. + # For API-only applications to support authentication "out-of-the-box", you will likely want to + # enable this with :database unless you are using a custom strategy. + # The supported strategies are: + # :database = Support basic authentication with authentication key + password + config.http_authenticatable = true + + # If 401 status code should be returned for AJAX requests. True by default. + # config.http_authenticatable_on_xhr = true + + # The realm used in Http Basic Authentication. 'Application' by default. + # config.http_authentication_realm = 'Application' + + # It will change confirmation, password recovery and other workflows + # to behave the same regardless if the e-mail provided was right or wrong. + # Does not affect registerable. + # config.paranoid = true + + # By default Devise will store the user in session. You can skip storage for + # particular strategies by setting this option. + # Notice that if you are skipping storage for all authentication paths, you + # may want to disable generating routes to Devise's sessions controller by + # passing skip: :sessions to `devise_for` in your config/routes.rb + config.skip_session_storage = [:http_auth] + + # By default, Devise cleans up the CSRF token on authentication to + # avoid CSRF token fixation attacks. This means that, when using AJAX + # requests for sign in and sign up, you need to get a new CSRF token + # from the server. You can disable this option at your own risk. + # config.clean_up_csrf_token_on_authentication = true + + # When false, Devise will not attempt to reload routes on eager load. + # This can reduce the time taken to boot the app but if your application + # requires the Devise mappings to be loaded during boot time the application + # won't boot properly. + # config.reload_routes = true + + # ==> Configuration for :database_authenticatable + # For bcrypt, this is the cost for hashing the password and defaults to 12. If + # using other algorithms, it sets how many times you want the password to be hashed. + # The number of stretches used for generating the hashed password are stored + # with the hashed password. This allows you to change the stretches without + # invalidating existing passwords. + # + # Limiting the stretches to just one in testing will increase the performance of + # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use + # a value less than 10 in other environments. Note that, for bcrypt (the default + # algorithm), the cost increases exponentially with the number of stretches (e.g. + # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). + config.stretches = Rails.env.test? ? 1 : 12 + + # Set up a pepper to generate the hashed password. + # config.pepper = '8b94639bc3aa104aa9b17554d6209cdc5bbbd767a3296f3f6600220cda59ddae62ddc13c37250d3602924f4e4d9c0e24788e318eba5c60dff77e478139388460' + + # Send a notification to the original email when the user's email is changed. + # config.send_email_changed_notification = false + + # Send a notification email when the user's password is changed. + # config.send_password_change_notification = false + + # ==> Configuration for :confirmable + # A period that the user is allowed to access the website even without + # confirming their account. For instance, if set to 2.days, the user will be + # able to access the website for two days without confirming their account, + # access will be blocked just in the third day. + # You can also set it to nil, which will allow the user to access the website + # without confirming their account. + # Default is 0.days, meaning the user cannot access the website without + # confirming their account. + # config.allow_unconfirmed_access_for = 2.days + + # A period that the user is allowed to confirm their account before their + # token becomes invalid. For example, if set to 3.days, the user can confirm + # their account within 3 days after the mail was sent, but on the fourth day + # their account can't be confirmed with the token any more. + # Default is nil, meaning there is no restriction on how long a user can take + # before confirming their account. + # config.confirm_within = 3.days + + # If true, requires any email changes to be confirmed (exactly the same way as + # initial account confirmation) to be applied. Requires additional unconfirmed_email + # db field (see migrations). Until confirmed, new email is stored in + # unconfirmed_email column, and copied to email column on successful confirmation. + config.reconfirmable = true + + # Defines which key will be used when confirming an account + # config.confirmation_keys = [:email] + + # ==> Configuration for :rememberable + # The time the user will be remembered without asking for credentials again. + # config.remember_for = 2.weeks + + # Invalidates all the remember me tokens when the user signs out. + config.expire_all_remember_me_on_sign_out = true + + # If true, extends the user's remember period when remembered via cookie. + # config.extend_remember_period = false + + # Options to be passed to the created cookie. For instance, you can set + # secure: true in order to force SSL only cookies. + # config.rememberable_options = {} + + # ==> Configuration for :validatable + # Range for password length. + config.password_length = 4..128 + + # Email regex used to validate email formats. It simply asserts that + # one (and only one) @ exists in the given string. This is mainly + # to give user feedback and not to assert the e-mail validity. + config.email_regexp = /\A[^@\s]+@[^@\s]+\z/ + + # ==> Configuration for :timeoutable + # The time you want to timeout the user session without activity. After this + # time the user will be asked for credentials again. Default is 30 minutes. + # config.timeout_in = 30.minutes + + # ==> Configuration for :lockable + # Defines which strategy will be used to lock an account. + # :failed_attempts = Locks an account after a number of failed attempts to sign in. + # :none = No lock strategy. You should handle locking by yourself. + # config.lock_strategy = :failed_attempts + + # Defines which key will be used when locking and unlocking an account + # config.unlock_keys = [:email] + + # Defines which strategy will be used to unlock an account. + # :email = Sends an unlock link to the user email + # :time = Re-enables login after a certain amount of time (see :unlock_in below) + # :both = Enables both strategies + # :none = No unlock strategy. You should handle unlocking by yourself. + # config.unlock_strategy = :both + + # Number of authentication tries before locking an account if lock_strategy + # is failed attempts. + # config.maximum_attempts = 20 + + # Time interval to unlock the account if :time is enabled as unlock_strategy. + # config.unlock_in = 1.hour + + # Warn on the last attempt before the account is locked. + # config.last_attempt_warning = true + + # ==> Configuration for :recoverable + # + # Defines which key will be used when recovering the password for an account + # config.reset_password_keys = [:email] + + # Time interval you can reset your password with a reset password key. + # Don't put a too small interval or your users won't have the time to + # change their passwords. + config.reset_password_within = 6.hours + + # When set to false, does not sign a user in automatically after their password is + # reset. Defaults to true, so a user is signed in automatically after a reset. + # config.sign_in_after_reset_password = true + + # ==> Configuration for :encryptable + # Allow you to use another hashing or encryption algorithm besides bcrypt (default). + # You can use :sha1, :sha512 or algorithms from others authentication tools as + # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20 + # for default behavior) and :restful_authentication_sha1 (then you should set + # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper). + # + # Require the `devise-encryptable` gem when using anything other than bcrypt + # config.encryptor = :sha512 + + # ==> Scopes configuration + # Turn scoped views on. Before rendering "sessions/new", it will first check for + # "users/sessions/new". It's turned off by default because it's slower if you + # are using only default views. + # config.scoped_views = false + + # Configure the default scope given to Warden. By default it's the first + # devise role declared in your routes (usually :user). + # config.default_scope = :user + + # Set this configuration to false if you want /users/sign_out to sign out + # only the current scope. By default, Devise signs out all scopes. + # config.sign_out_all_scopes = true + + # ==> Navigation configuration + # Lists the formats that should be treated as navigational. Formats like + # :html should redirect to the sign in page when the user does not have + # access, but formats like :xml or :json, should return 401. + # + # If you have any extra navigational formats, like :iphone or :mobile, you + # should add them to the navigational formats lists. + # + # The "*/*" below is required to match Internet Explorer requests. + # config.navigational_formats = ['*/*', :html, :turbo_stream] + + # The default HTTP method used to sign out a resource. Default is :delete. + config.sign_out_via = :delete + + # ==> OmniAuth + # Add a new OmniAuth provider. Check the wiki for more information on setting + # up on your models and hooks. + # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' + + # ==> Warden configuration + # If you want to use other strategies, that are not supported by Devise, or + # change the failure app, you can configure them inside the config.warden block. + # + # config.warden do |manager| + # manager.intercept_401 = false + # manager.default_strategies(scope: :user).unshift :some_external_strategy + # end + + # ==> Mountable engine configurations + # When using Devise inside an engine, let's call it `MyEngine`, and this engine + # is mountable, there are some extra configurations to be taken into account. + # The following options are available, assuming the engine is mounted as: + # + # mount MyEngine, at: '/my_engine' + # + # The router that invoked `devise_for`, in the example above, would be: + # config.router_name = :my_engine + # + # When using OmniAuth, Devise cannot automatically set OmniAuth path, + # so you need to do it manually. For the users scope, it would be: + # config.omniauth_path_prefix = '/my_engine/users/auth' + + # ==> Hotwire/Turbo configuration + # When using Devise with Hotwire/Turbo, the http status for error responses + # and some redirects must match the following. The default in Devise for existing + # apps is `200 OK` and `302 Found respectively`, but new apps are generated with + # these new defaults that match Hotwire/Turbo behavior. + # Note: These might become the new default in future versions of Devise. + config.responder.error_status = :unprocessable_entity + config.responder.redirect_status = :see_other + + # ==> Configuration for :registerable + + # When set to false, does not sign a user in automatically after their password is + # changed. Defaults to true, so a user is signed in automatically after changing a password. + # config.sign_in_after_change_password = true +end diff --git a/utils/build/docker/ruby/rails80/config/initializers/filter_parameter_logging.rb b/utils/build/docker/ruby/rails80/config/initializers/filter_parameter_logging.rb new file mode 100644 index 00000000000..4b34a036689 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,6 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [ + :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn +] diff --git a/utils/build/docker/ruby/rails80/config/initializers/inflections.rb b/utils/build/docker/ruby/rails80/config/initializers/inflections.rb new file mode 100644 index 00000000000..3860f659ead --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, "\\1en" +# inflect.singular /^(ox)en/i, "\\1" +# inflect.irregular "person", "people" +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym "RESTful" +# end diff --git a/utils/build/docker/ruby/rails80/config/initializers/permissions_policy.rb b/utils/build/docker/ruby/rails80/config/initializers/permissions_policy.rb new file mode 100644 index 00000000000..00f64d71b03 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/initializers/permissions_policy.rb @@ -0,0 +1,11 @@ +# Define an application-wide HTTP permissions policy. For further +# information see https://developers.google.com/web/updates/2018/06/feature-policy +# +# Rails.application.config.permissions_policy do |f| +# f.camera :none +# f.gyroscope :none +# f.microphone :none +# f.usb :none +# f.fullscreen :self +# f.payment :self, "https://secure.example.com" +# end diff --git a/utils/build/docker/ruby/rails80/config/locales/en.yml b/utils/build/docker/ruby/rails80/config/locales/en.yml new file mode 100644 index 00000000000..8ca56fc74f3 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/locales/en.yml @@ -0,0 +1,33 @@ +# Files in the config/locales directory are used for internationalization +# and are automatically loaded by Rails. If you want to use locales other +# than English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t "hello" +# +# In views, this is aliased to just `t`: +# +# <%= t("hello") %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# The following keys must be escaped otherwise they will not be retrieved by +# the default I18n backend: +# +# true, false, on, off, yes, no +# +# Instead, surround them with single quotes. +# +# en: +# "true": "foo" +# +# To learn more, please read the Rails Internationalization guide +# available at https://guides.rubyonrails.org/i18n.html. + +en: + hello: "Hello world" diff --git a/utils/build/docker/ruby/rails80/config/puma.rb b/utils/build/docker/ruby/rails80/config/puma.rb new file mode 100644 index 00000000000..daaf0369998 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/puma.rb @@ -0,0 +1,43 @@ +# Puma can serve each request in a thread from an internal thread pool. +# The `threads` method setting takes two numbers: a minimum and maximum. +# Any libraries that use thread pools should be configured to match +# the maximum value specified for Puma. Default is set to 5 threads for minimum +# and maximum; this matches the default thread size of Active Record. +# +max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } +min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } +threads min_threads_count, max_threads_count + +# Specifies the `worker_timeout` threshold that Puma will use to wait before +# terminating a worker in development environments. +# +worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" + +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +# +port ENV.fetch("PORT") { 3000 } + +# Specifies the `environment` that Puma will run in. +# +environment ENV.fetch("RAILS_ENV") { "development" } + +# Specifies the `pidfile` that Puma will use. +pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } + +# Specifies the number of `workers` to boot in clustered mode. +# Workers are forked web server processes. If using threads and workers together +# the concurrency of the application would be max `threads` * `workers`. +# Workers do not work on JRuby or Windows (both of which do not support +# processes). +# +# workers ENV.fetch("WEB_CONCURRENCY") { 2 } + +# Use the `preload_app!` method when specifying a `workers` number. +# This directive tells Puma to first boot the application and load code +# before forking the application. This takes advantage of Copy On Write +# process behavior so workers use less memory. +# +# preload_app! + +# Allow puma to be restarted by `bin/rails restart` command. +plugin :tmp_restart diff --git a/utils/build/docker/ruby/rails80/config/routes.rb b/utils/build/docker/ruby/rails80/config/routes.rb new file mode 100644 index 00000000000..22c3f8c1265 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/routes.rb @@ -0,0 +1,50 @@ +Rails.application.routes.draw do + # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html + + # Defines the root path route ("/") + # root "articles#index" + + get '/' => 'system_test#root' + post '/' => 'system_test#root' + + get '/healthcheck' => 'system_test#healthcheck' + + get '/waf' => 'system_test#waf' + post '/waf' => 'system_test#waf' + get '/waf/*other' => 'system_test#waf' + post '/waf/*other' => 'system_test#waf' + + get '/kafka/produce' => 'system_test#kafka_produce' + get '/kafka/consume' => 'system_test#kafka_consume' + + get '/params/:value' => 'system_test#handle_path_params' + get '/spans' => 'system_test#generate_spans' + get '/status' => 'system_test#status' + get '/read_file' => 'system_test#read_file' + get '/make_distant_call' => 'system_test#make_distant_call' + + get '/headers' => 'system_test#test_headers' + get '/identify' => 'system_test#identify' + + get 'user_login_success_event' => 'system_test#user_login_success_event' + get 'user_login_failure_event' => 'system_test#user_login_failure_event' + get 'custom_event' => 'system_test#custom_event' + + %i[get post].each do |request_method| + send(request_method, '/tag_value/:tag_value/:status_code' => 'system_test#tag_value') + end + match '/tag_value/:tag_value/:status_code' => 'system_test#tag_value', via: :options + get '/users' => 'system_test#users' + + devise_for :users + %i[get post].each do |request_method| + # We have to provide format: false to make sure the Test_DiscoveryScan test do not break + # https://github.com/DataDog/system-tests/blob/515310b5fb1fd0792fc283c9ee134ab3803d6e7c/tests/appsec/waf/test_rules.py#L374 + # The test hits '/login.pwd' and expects a 404. + # By default rails parse format by default and consider the route to exists. We want want onlt '/login' to exists + send(request_method, '/login' => 'system_test#login', format: false) + end + + get '/requestdownstream' => 'system_test#request_downstream' + get '/returnheaders' => 'system_test#return_headers' +end diff --git a/utils/build/docker/ruby/rails80/config/storage.yml b/utils/build/docker/ruby/rails80/config/storage.yml new file mode 100644 index 00000000000..4942ab66948 --- /dev/null +++ b/utils/build/docker/ruby/rails80/config/storage.yml @@ -0,0 +1,34 @@ +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +# Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) +# amazon: +# service: S3 +# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> +# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> +# region: us-east-1 +# bucket: your_own_bucket-<%= Rails.env %> + +# Remember not to checkin your GCS keyfile to a repository +# google: +# service: GCS +# project: your_project +# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> +# bucket: your_own_bucket-<%= Rails.env %> + +# Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) +# microsoft: +# service: AzureStorage +# storage_account_name: your_account_name +# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> +# container: your_container_name-<%= Rails.env %> + +# mirror: +# service: Mirror +# primary: local +# mirrors: [ amazon, google, microsoft ] diff --git a/utils/build/docker/ruby/rails80/db/migrate/20230621141816_devise_create_users.rb b/utils/build/docker/ruby/rails80/db/migrate/20230621141816_devise_create_users.rb new file mode 100644 index 00000000000..0f43e58c82c --- /dev/null +++ b/utils/build/docker/ruby/rails80/db/migrate/20230621141816_devise_create_users.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +class DeviseCreateUsers < ActiveRecord::Migration[7.0] + def change + create_table :users, id: :string do |t| + ## Database authenticatable + t.string :username, null: false, default: "" + t.string :email, null: false, default: "" + t.string :encrypted_password, null: false, default: "" + + ## Recoverable + t.string :reset_password_token + t.datetime :reset_password_sent_at + + ## Rememberable + t.datetime :remember_created_at + + ## Trackable + # t.integer :sign_in_count, default: 0, null: false + # t.datetime :current_sign_in_at + # t.datetime :last_sign_in_at + # t.string :current_sign_in_ip + # t.string :last_sign_in_ip + + ## Confirmable + # t.string :confirmation_token + # t.datetime :confirmed_at + # t.datetime :confirmation_sent_at + # t.string :unconfirmed_email # Only if using reconfirmable + + ## Lockable + # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts + # t.string :unlock_token # Only if unlock strategy is :email or :both + # t.datetime :locked_at + + + t.timestamps null: false + end + + add_index :users, :email, unique: true + add_index :users, :reset_password_token, unique: true + # add_index :users, :confirmation_token, unique: true + # add_index :users, :unlock_token, unique: true + end +end diff --git a/utils/build/docker/ruby/rails41/db/seeds.rb b/utils/build/docker/ruby/rails80/db/seeds.rb similarity index 100% rename from utils/build/docker/ruby/rails41/db/seeds.rb rename to utils/build/docker/ruby/rails80/db/seeds.rb diff --git a/utils/build/docker/ruby/rails80/lib/assets/.keep b/utils/build/docker/ruby/rails80/lib/assets/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/lib/tasks/.keep b/utils/build/docker/ruby/rails80/lib/tasks/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/public/404.html b/utils/build/docker/ruby/rails80/public/404.html new file mode 100644 index 00000000000..2be3af26fc5 --- /dev/null +++ b/utils/build/docker/ruby/rails80/public/404.html @@ -0,0 +1,67 @@ + + + + The page you were looking for doesn't exist (404) + + + + + + +
+
+

The page you were looking for doesn't exist.

+

You may have mistyped the address or the page may have moved.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/utils/build/docker/ruby/rails80/public/422.html b/utils/build/docker/ruby/rails80/public/422.html new file mode 100644 index 00000000000..c08eac0d1df --- /dev/null +++ b/utils/build/docker/ruby/rails80/public/422.html @@ -0,0 +1,67 @@ + + + + The change you wanted was rejected (422) + + + + + + +
+
+

The change you wanted was rejected.

+

Maybe you tried to change something you didn't have access to.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/utils/build/docker/ruby/rails80/public/500.html b/utils/build/docker/ruby/rails80/public/500.html new file mode 100644 index 00000000000..78a030af22e --- /dev/null +++ b/utils/build/docker/ruby/rails80/public/500.html @@ -0,0 +1,66 @@ + + + + We're sorry, but something went wrong (500) + + + + + + +
+
+

We're sorry, but something went wrong.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/utils/build/docker/ruby/rails80/public/apple-touch-icon-precomposed.png b/utils/build/docker/ruby/rails80/public/apple-touch-icon-precomposed.png new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/public/apple-touch-icon.png b/utils/build/docker/ruby/rails80/public/apple-touch-icon.png new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/public/favicon.ico b/utils/build/docker/ruby/rails80/public/favicon.ico new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/public/robots.txt b/utils/build/docker/ruby/rails80/public/robots.txt new file mode 100644 index 00000000000..c19f78ab683 --- /dev/null +++ b/utils/build/docker/ruby/rails80/public/robots.txt @@ -0,0 +1 @@ +# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file diff --git a/utils/build/docker/ruby/rails80/storage/.keep b/utils/build/docker/ruby/rails80/storage/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/test/application_system_test_case.rb b/utils/build/docker/ruby/rails80/test/application_system_test_case.rb new file mode 100644 index 00000000000..d19212abd5c --- /dev/null +++ b/utils/build/docker/ruby/rails80/test/application_system_test_case.rb @@ -0,0 +1,5 @@ +require "test_helper" + +class ApplicationSystemTestCase < ActionDispatch::SystemTestCase + driven_by :selenium, using: :chrome, screen_size: [1400, 1400] +end diff --git a/utils/build/docker/ruby/rails80/test/channels/application_cable/connection_test.rb b/utils/build/docker/ruby/rails80/test/channels/application_cable/connection_test.rb new file mode 100644 index 00000000000..800405f15e6 --- /dev/null +++ b/utils/build/docker/ruby/rails80/test/channels/application_cable/connection_test.rb @@ -0,0 +1,11 @@ +require "test_helper" + +class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase + # test "connects with cookies" do + # cookies.signed[:user_id] = 42 + # + # connect + # + # assert_equal connection.user_id, "42" + # end +end diff --git a/utils/build/docker/ruby/rails80/test/controllers/.keep b/utils/build/docker/ruby/rails80/test/controllers/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/test/fixtures/files/.keep b/utils/build/docker/ruby/rails80/test/fixtures/files/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/test/helpers/.keep b/utils/build/docker/ruby/rails80/test/helpers/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/test/integration/.keep b/utils/build/docker/ruby/rails80/test/integration/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/test/mailers/.keep b/utils/build/docker/ruby/rails80/test/mailers/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/test/models/.keep b/utils/build/docker/ruby/rails80/test/models/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/test/system/.keep b/utils/build/docker/ruby/rails80/test/system/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/test/test_helper.rb b/utils/build/docker/ruby/rails80/test/test_helper.rb new file mode 100644 index 00000000000..d713e377c94 --- /dev/null +++ b/utils/build/docker/ruby/rails80/test/test_helper.rb @@ -0,0 +1,13 @@ +ENV["RAILS_ENV"] ||= "test" +require_relative "../config/environment" +require "rails/test_help" + +class ActiveSupport::TestCase + # Run tests in parallel with specified workers + parallelize(workers: :number_of_processors) + + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + + # Add more helper methods to be used by all tests here... +end diff --git a/utils/build/docker/ruby/rails80/tmp/.keep b/utils/build/docker/ruby/rails80/tmp/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/tmp/pids/.keep b/utils/build/docker/ruby/rails80/tmp/pids/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/tmp/storage/.keep b/utils/build/docker/ruby/rails80/tmp/storage/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/vendor/.keep b/utils/build/docker/ruby/rails80/vendor/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/rails80/vendor/javascript/.keep b/utils/build/docker/ruby/rails80/vendor/javascript/.keep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/build/docker/ruby/sinatra14.Dockerfile b/utils/build/docker/ruby/sinatra14.Dockerfile index 73243a0b45a..f5825936296 100644 --- a/utils/build/docker/ruby/sinatra14.Dockerfile +++ b/utils/build/docker/ruby/sinatra14.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:2.7.6-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:2.7 RUN mkdir -p /app WORKDIR /app diff --git a/utils/build/docker/ruby/sinatra14/app.rb b/utils/build/docker/ruby/sinatra14/app.rb index 69ffc224a9f..a28dddff0e3 100644 --- a/utils/build/docker/ruby/sinatra14/app.rb +++ b/utils/build/docker/ruby/sinatra14/app.rb @@ -4,14 +4,10 @@ require "uri" require 'json' -begin - require 'ddtrace/auto_instrument' -rescue LoadError -end - begin require 'datadog/auto_instrument' rescue LoadError + require 'ddtrace/auto_instrument' end Datadog.configure do |c| @@ -37,6 +33,22 @@ 'Hello, world!' end +get '/healthcheck' do + content_type :json + + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + { + status: 'ok', + library: { + language: 'ruby', + version: version + } + }.to_json + +end + post '/' do 'Hello, world!' end @@ -184,3 +196,30 @@ 'Hello, user!' end + +get '/requestdownstream' do + content_type :json + + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + ext_response.body +end + +get '/returnheaders' do + content_type :json + + # Convert headers from Rack format to browser format + + headers = request.env.select { |k, v| k.start_with?('HTTP_') } + headers = headers.transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') } + + headers.to_json +end diff --git a/utils/build/docker/ruby/sinatra20.Dockerfile b/utils/build/docker/ruby/sinatra20.Dockerfile index 9d251fd76e2..83904800422 100644 --- a/utils/build/docker/ruby/sinatra20.Dockerfile +++ b/utils/build/docker/ruby/sinatra20.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:2.7.6-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:2.7 RUN mkdir -p /app WORKDIR /app diff --git a/utils/build/docker/ruby/sinatra20/app.rb b/utils/build/docker/ruby/sinatra20/app.rb index e33c76c63d8..7ab82e50435 100644 --- a/utils/build/docker/ruby/sinatra20/app.rb +++ b/utils/build/docker/ruby/sinatra20/app.rb @@ -4,14 +4,10 @@ require "uri" require 'json' -begin - require 'ddtrace/auto_instrument' -rescue LoadError -end - begin require 'datadog/auto_instrument' rescue LoadError + require 'ddtrace/auto_instrument' end @@ -38,6 +34,22 @@ 'Hello, world!' end +get '/healthcheck' do + content_type :json + + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + { + status: 'ok', + library: { + language: 'ruby', + version: version + } + }.to_json + +end + post '/' do 'Hello, world!' end @@ -184,3 +196,30 @@ 'Hello, user!' end + +get '/requestdownstream' do + content_type :json + + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + ext_response.body +end + +get '/returnheaders' do + content_type :json + + # Convert headers from Rack format to browser format + + headers = request.env.select { |k, v| k.start_with?('HTTP_') } + headers = headers.transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') } + + headers.to_json +end diff --git a/utils/build/docker/ruby/sinatra21.Dockerfile b/utils/build/docker/ruby/sinatra21.Dockerfile index ac919cd7c10..d667f98acc4 100644 --- a/utils/build/docker/ruby/sinatra21.Dockerfile +++ b/utils/build/docker/ruby/sinatra21.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:3.1.1-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:3.1 RUN mkdir -p /app WORKDIR /app diff --git a/utils/build/docker/ruby/sinatra21/app.rb b/utils/build/docker/ruby/sinatra21/app.rb index e33c76c63d8..7ab82e50435 100644 --- a/utils/build/docker/ruby/sinatra21/app.rb +++ b/utils/build/docker/ruby/sinatra21/app.rb @@ -4,14 +4,10 @@ require "uri" require 'json' -begin - require 'ddtrace/auto_instrument' -rescue LoadError -end - begin require 'datadog/auto_instrument' rescue LoadError + require 'ddtrace/auto_instrument' end @@ -38,6 +34,22 @@ 'Hello, world!' end +get '/healthcheck' do + content_type :json + + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + { + status: 'ok', + library: { + language: 'ruby', + version: version + } + }.to_json + +end + post '/' do 'Hello, world!' end @@ -184,3 +196,30 @@ 'Hello, user!' end + +get '/requestdownstream' do + content_type :json + + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + ext_response.body +end + +get '/returnheaders' do + content_type :json + + # Convert headers from Rack format to browser format + + headers = request.env.select { |k, v| k.start_with?('HTTP_') } + headers = headers.transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') } + + headers.to_json +end diff --git a/utils/build/docker/ruby/sinatra22.Dockerfile b/utils/build/docker/ruby/sinatra22.Dockerfile index 9e6d27d477c..bcd9f496ab7 100644 --- a/utils/build/docker/ruby/sinatra22.Dockerfile +++ b/utils/build/docker/ruby/sinatra22.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:3.1.1-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:3.1 RUN mkdir -p /app WORKDIR /app diff --git a/utils/build/docker/ruby/sinatra22/app.rb b/utils/build/docker/ruby/sinatra22/app.rb index 97934fffa6d..644cd639ca1 100644 --- a/utils/build/docker/ruby/sinatra22/app.rb +++ b/utils/build/docker/ruby/sinatra22/app.rb @@ -4,14 +4,10 @@ require "uri" require 'json' -begin - require 'ddtrace/auto_instrument' -rescue LoadError -end - begin require 'datadog/auto_instrument' rescue LoadError + require 'ddtrace/auto_instrument' end Datadog.configure do |c| @@ -37,6 +33,22 @@ 'Hello, world!' end +get '/healthcheck' do + content_type :json + + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + { + status: 'ok', + library: { + language: 'ruby', + version: version + } + }.to_json + +end + post '/' do 'Hello, world!' end @@ -183,3 +195,30 @@ 'Hello, user!' end + +get '/requestdownstream' do + content_type :json + + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + ext_response.body +end + +get '/returnheaders' do + content_type :json + + # Convert headers from Rack format to browser format + + headers = request.env.select { |k, v| k.start_with?('HTTP_') } + headers = headers.transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') } + + headers.to_json +end diff --git a/utils/build/docker/ruby/sinatra30.Dockerfile b/utils/build/docker/ruby/sinatra30.Dockerfile index bdf1fd0c1e6..99244c1935a 100644 --- a/utils/build/docker/ruby/sinatra30.Dockerfile +++ b/utils/build/docker/ruby/sinatra30.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:3.2.0-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:3.2 RUN mkdir -p /app WORKDIR /app diff --git a/utils/build/docker/ruby/sinatra30/app.rb b/utils/build/docker/ruby/sinatra30/app.rb index 97934fffa6d..644cd639ca1 100644 --- a/utils/build/docker/ruby/sinatra30/app.rb +++ b/utils/build/docker/ruby/sinatra30/app.rb @@ -4,14 +4,10 @@ require "uri" require 'json' -begin - require 'ddtrace/auto_instrument' -rescue LoadError -end - begin require 'datadog/auto_instrument' rescue LoadError + require 'ddtrace/auto_instrument' end Datadog.configure do |c| @@ -37,6 +33,22 @@ 'Hello, world!' end +get '/healthcheck' do + content_type :json + + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + { + status: 'ok', + library: { + language: 'ruby', + version: version + } + }.to_json + +end + post '/' do 'Hello, world!' end @@ -183,3 +195,30 @@ 'Hello, user!' end + +get '/requestdownstream' do + content_type :json + + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + ext_response.body +end + +get '/returnheaders' do + content_type :json + + # Convert headers from Rack format to browser format + + headers = request.env.select { |k, v| k.start_with?('HTTP_') } + headers = headers.transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') } + + headers.to_json +end diff --git a/utils/build/docker/ruby/sinatra31.Dockerfile b/utils/build/docker/ruby/sinatra31.Dockerfile index 6a674841d25..e47a8c19465 100644 --- a/utils/build/docker/ruby/sinatra31.Dockerfile +++ b/utils/build/docker/ruby/sinatra31.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:3.2.0-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:3.2 RUN mkdir -p /app WORKDIR /app diff --git a/utils/build/docker/ruby/sinatra31/app.rb b/utils/build/docker/ruby/sinatra31/app.rb index 97934fffa6d..644cd639ca1 100644 --- a/utils/build/docker/ruby/sinatra31/app.rb +++ b/utils/build/docker/ruby/sinatra31/app.rb @@ -4,14 +4,10 @@ require "uri" require 'json' -begin - require 'ddtrace/auto_instrument' -rescue LoadError -end - begin require 'datadog/auto_instrument' rescue LoadError + require 'ddtrace/auto_instrument' end Datadog.configure do |c| @@ -37,6 +33,22 @@ 'Hello, world!' end +get '/healthcheck' do + content_type :json + + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + { + status: 'ok', + library: { + language: 'ruby', + version: version + } + }.to_json + +end + post '/' do 'Hello, world!' end @@ -183,3 +195,30 @@ 'Hello, user!' end + +get '/requestdownstream' do + content_type :json + + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + ext_response.body +end + +get '/returnheaders' do + content_type :json + + # Convert headers from Rack format to browser format + + headers = request.env.select { |k, v| k.start_with?('HTTP_') } + headers = headers.transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') } + + headers.to_json +end diff --git a/utils/build/docker/ruby/sinatra32.Dockerfile b/utils/build/docker/ruby/sinatra32.Dockerfile index 7e9dabc0f12..5cd8e324fb2 100644 --- a/utils/build/docker/ruby/sinatra32.Dockerfile +++ b/utils/build/docker/ruby/sinatra32.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:3.2.0-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:3.2 RUN mkdir -p /app WORKDIR /app diff --git a/utils/build/docker/ruby/sinatra32/app.rb b/utils/build/docker/ruby/sinatra32/app.rb index 97934fffa6d..644cd639ca1 100644 --- a/utils/build/docker/ruby/sinatra32/app.rb +++ b/utils/build/docker/ruby/sinatra32/app.rb @@ -4,14 +4,10 @@ require "uri" require 'json' -begin - require 'ddtrace/auto_instrument' -rescue LoadError -end - begin require 'datadog/auto_instrument' rescue LoadError + require 'ddtrace/auto_instrument' end Datadog.configure do |c| @@ -37,6 +33,22 @@ 'Hello, world!' end +get '/healthcheck' do + content_type :json + + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + { + status: 'ok', + library: { + language: 'ruby', + version: version + } + }.to_json + +end + post '/' do 'Hello, world!' end @@ -183,3 +195,30 @@ 'Hello, user!' end + +get '/requestdownstream' do + content_type :json + + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + ext_response.body +end + +get '/returnheaders' do + content_type :json + + # Convert headers from Rack format to browser format + + headers = request.env.select { |k, v| k.start_with?('HTTP_') } + headers = headers.transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') } + + headers.to_json +end diff --git a/utils/build/docker/ruby/sinatra40.Dockerfile b/utils/build/docker/ruby/sinatra40.Dockerfile index 9c8c3ea8c4d..ce5788e650d 100644 --- a/utils/build/docker/ruby/sinatra40.Dockerfile +++ b/utils/build/docker/ruby/sinatra40.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:3.2.0-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:3.2 RUN mkdir -p /app WORKDIR /app diff --git a/utils/build/docker/ruby/sinatra40/app.rb b/utils/build/docker/ruby/sinatra40/app.rb index 97934fffa6d..644cd639ca1 100644 --- a/utils/build/docker/ruby/sinatra40/app.rb +++ b/utils/build/docker/ruby/sinatra40/app.rb @@ -4,14 +4,10 @@ require "uri" require 'json' -begin - require 'ddtrace/auto_instrument' -rescue LoadError -end - begin require 'datadog/auto_instrument' rescue LoadError + require 'ddtrace/auto_instrument' end Datadog.configure do |c| @@ -37,6 +33,22 @@ 'Hello, world!' end +get '/healthcheck' do + content_type :json + + gemspec = Gem.loaded_specs['datadog'] || Gem.loaded_specs['ddtrace'] + version = gemspec.version.to_s + version = "#{version}-dev" unless gemspec.source.is_a?(Bundler::Source::Rubygems) + { + status: 'ok', + library: { + language: 'ruby', + version: version + } + }.to_json + +end + post '/' do 'Hello, world!' end @@ -183,3 +195,30 @@ 'Hello, user!' end + +get '/requestdownstream' do + content_type :json + + uri = URI('http://localhost:7777/returnheaders') + ext_request = nil + ext_response = nil + + Net::HTTP.start(uri.host, uri.port) do |http| + ext_request = Net::HTTP::Get.new(uri) + + ext_response = http.request(ext_request) + end + + ext_response.body +end + +get '/returnheaders' do + content_type :json + + # Convert headers from Rack format to browser format + + headers = request.env.select { |k, v| k.start_with?('HTTP_') } + headers = headers.transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') } + + headers.to_json +end diff --git a/utils/build/docker/ruby/uds-sinatra.Dockerfile b/utils/build/docker/ruby/uds-sinatra.Dockerfile index 350aeb77580..5a35b08deb0 100644 --- a/utils/build/docker/ruby/uds-sinatra.Dockerfile +++ b/utils/build/docker/ruby/uds-sinatra.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/datadog/dd-trace-rb/ruby:3.1.1-dd +FROM ghcr.io/datadog/images-rb/engines/ruby:3.1 RUN mkdir -p /app WORKDIR /app diff --git a/utils/build/docker/runner.Dockerfile b/utils/build/docker/runner.Dockerfile index 14c8c81d146..9582f9e2c93 100644 --- a/utils/build/docker/runner.Dockerfile +++ b/utils/build/docker/runner.Dockerfile @@ -1,5 +1,4 @@ -FROM python:3.9 - +FROM python:3.12 RUN mkdir /app WORKDIR /app @@ -10,21 +9,8 @@ COPY build.sh . COPY utils/build/build.sh utils/build/build.sh RUN mkdir -p /app/utils/build/docker && ./build.sh -i runner -# basically everything except utils/build -COPY utils/assets /app/utils/assets -COPY utils/build /app/utils/build -COPY utils/_context /app/utils/_context -COPY utils/grpc /app/utils/grpc -COPY utils/interfaces /app/utils/interfaces -COPY utils/k8s_lib_injection /app/utils/k8s_lib_injection -COPY utils/onboarding /app/utils/onboarding -COPY utils/parametric /app/utils/parametric -COPY utils/proxy /app/utils/proxy -COPY utils/scripts /app/utils/scripts -COPY utils/virtual_machine /app/utils/virtual_machine -COPY utils/otel_validators /app/utils/otel_validators -COPY utils/*.py /app/utils/ +COPY utils/ /app/utils/ # tests COPY tests /app/tests COPY parametric /app/parametric diff --git a/utils/build/docker/set-system-tests-weblog-env.Dockerfile b/utils/build/docker/set-system-tests-weblog-env.Dockerfile deleted file mode 100644 index 39225d4b47d..00000000000 --- a/utils/build/docker/set-system-tests-weblog-env.Dockerfile +++ /dev/null @@ -1,63 +0,0 @@ -FROM system_tests/weblog - -# Datadog setup -ENV DD_SERVICE=weblog -ENV DD_VERSION=1.0.0 -ENV DD_TAGS='key1:val1, key2 : val2 ' -ENV DD_ENV=system-tests -ENV DD_TRACE_DEBUG=true -ENV DD_TRACE_LOG_DIRECTORY=/var/log/system-tests -ENV DD_TRACE_COMPUTE_STATS=true - -ENV SOME_SECRET_ENV=leaked-env-var - -# 10 seconds -ENV DD_APPSEC_WAF_TIMEOUT=10000000 -ENV DD_APPSEC_TRACE_RATE_LIMIT=10000 - -ENV DD_IAST_ENABLED=true -ENV DD_IAST_REQUEST_SAMPLING=100 -ENV DD_IAST_MAX_CONCURRENT_REQUESTS=10 -ENV DD_IAST_DEBUG_ENABLED=true -ENV DD_IAST_CONTEXT_MODE=GLOBAL - -ENV DD_INSTRUMENTATION_TELEMETRY_ENABLED=true -ENV DD_TELEMETRY_HEARTBEAT_INTERVAL=2 -ENV DD_TELEMETRY_METRICS_ENABLED=true -# Python lib has different env var until we enable Telemetry Metrics by default -ENV _DD_TELEMETRY_METRICS_ENABLED=true -ENV DD_TELEMETRY_METRICS_INTERVAL_SECONDS=2 -ENV DD_TELEMETRY_LOG_COLLECTION_ENABLED=true - -ARG SYSTEM_TESTS_LIBRARY -ENV SYSTEM_TESTS_LIBRARY=$SYSTEM_TESTS_LIBRARY - -ARG SYSTEM_TESTS_WEBLOG_VARIANT -ENV SYSTEM_TESTS_WEBLOG_VARIANT=$SYSTEM_TESTS_WEBLOG_VARIANT - -ARG SYSTEM_TESTS_LIBRARY_VERSION -ENV SYSTEM_TESTS_LIBRARY_VERSION=$SYSTEM_TESTS_LIBRARY_VERSION - -ARG SYSTEM_TESTS_LIBDDWAF_VERSION -ENV SYSTEM_TESTS_LIBDDWAF_VERSION=$SYSTEM_TESTS_LIBDDWAF_VERSION - -ARG SYSTEM_TESTS_APPSEC_EVENT_RULES_VERSION -ENV SYSTEM_TESTS_APPSEC_EVENT_RULES_VERSION=$SYSTEM_TESTS_APPSEC_EVENT_RULES_VERSION - -# Flush telemetry messages faster -ENV DD_HEARTBEAT_TELEMETRY_INTERVAL=5 - -# files for exotic scenarios -RUN echo "corrupted::data" > /appsec_corrupted_rules.yml -COPY tests/appsec/custom_rules.json /appsec_custom_rules.json -COPY tests/appsec/custom_rules_with_errors.json /appsec_custom_rules_with_errors.json -COPY tests/appsec/blocking_rule.json /appsec_blocking_rule.json -COPY tests/appsec/rasp/rasp_ruleset.json /appsec_rasp_ruleset.json - -# for remote configuration tests -ENV DD_RC_TUF_ROOT='{"signed":{"_type":"root","spec_version":"1.0","version":1,"expires":"2032-05-29T12:49:41.030418-04:00","keys":{"ed7672c9a24abda78872ee32ee71c7cb1d5235e8db4ecbf1ca28b9c50eb75d9e":{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"7d3102e39abe71044d207550bda239c71380d013ec5a115f79f51622630054e6"}}},"roles":{"root":{"keyids":["ed7672c9a24abda78872ee32ee71c7cb1d5235e8db4ecbf1ca28b9c50eb75d9e"],"threshold":1},"snapshot":{"keyids":["ed7672c9a24abda78872ee32ee71c7cb1d5235e8db4ecbf1ca28b9c50eb75d9e"],"threshold":1},"targets":{"keyids":["ed7672c9a24abda78872ee32ee71c7cb1d5235e8db4ecbf1ca28b9c50eb75d9e"],"threshold":1},"timestsmp":{"keyids":["ed7672c9a24abda78872ee32ee71c7cb1d5235e8db4ecbf1ca28b9c50eb75d9e"],"threshold":1}},"consistent_snapshot":true},"signatures":[{"keyid":"ed7672c9a24abda78872ee32ee71c7cb1d5235e8db4ecbf1ca28b9c50eb75d9e","sig":"d7e24828d1d3104e48911860a13dd6ad3f4f96d45a9ea28c4a0f04dbd3ca6c205ed406523c6c4cacfb7ebba68f7e122e42746d1c1a83ffa89c8bccb6f7af5e06"}]}' - -COPY ./utils/build/docker/weblog-cmd.sh ./weblog-cmd.sh -RUN chmod +x app.sh -RUN chmod +x weblog-cmd.sh -CMD [ "./weblog-cmd.sh" ] diff --git a/utils/build/docker/weblog-cmd.sh b/utils/build/docker/weblog-cmd.sh deleted file mode 100755 index 81c99b98ecd..00000000000 --- a/utils/build/docker/weblog-cmd.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. -# This product includes software developed at Datadog (https://www.datadoghq.com/). -# Copyright 2021 Datadog, Inc. - - -########################################################################################## -# This is an entrypoint file that all containers run in system-tests are funneled through. -########################################################################################## - -set -eu - -echo "Configuration script executed from: ${PWD}" -BASEDIR=$(dirname $0) -echo "Configuration script location: ${BASEDIR}" - -./app.sh diff --git a/utils/build/ssi/base/base_deps.Dockerfile b/utils/build/ssi/base/base_deps.Dockerfile new file mode 100644 index 00000000000..864bfa54a93 --- /dev/null +++ b/utils/build/ssi/base/base_deps.Dockerfile @@ -0,0 +1,11 @@ +ARG BASE_IMAGE +FROM ${BASE_IMAGE} as app_base +LABEL org.opencontainers.image.source=https://github.com/DataDog/guardrails-testing +USER root +WORKDIR /workdir +ARG ARCH +COPY base/install_os_deps.sh ./ +COPY base/healthcheck.sh / +COPY base/tested_components.sh / + +RUN ./install_os_deps.sh ${ARCH} diff --git a/utils/build/ssi/base/base_lang.Dockerfile b/utils/build/ssi/base/base_lang.Dockerfile new file mode 100644 index 00000000000..5c9981fe161 --- /dev/null +++ b/utils/build/ssi/base/base_lang.Dockerfile @@ -0,0 +1,14 @@ +ARG BASE_IMAGE +FROM ${BASE_IMAGE} as app_base +LABEL org.opencontainers.image.source=https://github.com/DataDog/guardrails-testing + +WORKDIR /workdir +ARG ARCH +COPY base/install_os_deps.sh ./ +COPY base/healthcheck.sh / +COPY base/tested_components.sh / +RUN ./install_os_deps.sh ${ARCH} +ARG DD_LANG +ARG RUNTIME_VERSIONS= +COPY base/${DD_LANG}_install_runtimes.sh ./ +RUN ./${DD_LANG}_install_runtimes.sh ${RUNTIME_VERSIONS} \ No newline at end of file diff --git a/utils/build/ssi/base/base_ssi.Dockerfile b/utils/build/ssi/base/base_ssi.Dockerfile new file mode 100644 index 00000000000..ae23c524096 --- /dev/null +++ b/utils/build/ssi/base/base_ssi.Dockerfile @@ -0,0 +1,17 @@ +ARG BASE_IMAGE + +FROM ${BASE_IMAGE} + +WORKDIR /workdir + +COPY ./base/install_script_ssi.sh ./ + +ARG DD_API_KEY=deadbeef + +ARG DD_LANG +ENV DD_APM_INSTRUMENTATION_LIBRARIES=${DD_LANG} + +RUN ./install_script_ssi.sh + +ENV DD_APM_INSTRUMENTATION_DEBUG=true +ENV DD_INSTRUMENT_SERVICE_WITH_APM=true \ No newline at end of file diff --git a/utils/build/ssi/base/base_ssi_installer.Dockerfile b/utils/build/ssi/base/base_ssi_installer.Dockerfile new file mode 100755 index 00000000000..7ad8aa299be --- /dev/null +++ b/utils/build/ssi/base/base_ssi_installer.Dockerfile @@ -0,0 +1,11 @@ +ARG BASE_IMAGE + +FROM ${BASE_IMAGE} + +WORKDIR /workdir + +COPY ./base/install_script_ssi_installer.sh ./ + +ARG DD_API_KEY=deadbeef + +RUN ./install_script_ssi_installer.sh diff --git a/utils/build/ssi/base/dotnet_install_runtimes.sh b/utils/build/ssi/base/dotnet_install_runtimes.sh new file mode 100755 index 00000000000..b54396b3ab6 --- /dev/null +++ b/utils/build/ssi/base/dotnet_install_runtimes.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +export DOTNET_VERSION=$1 +set -e + +curl -sSL https://dot.net/v1/dotnet-install.sh --output dotnet-install.sh \ + && chmod +x ./dotnet-install.sh \ + && ./dotnet-install.sh --version "$DOTNET_VERSION" --install-dir /usr/share/dotnet \ + && rm ./dotnet-install.sh \ + && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet diff --git a/utils/build/ssi/base/healthcheck.sh b/utils/build/ssi/base/healthcheck.sh new file mode 100755 index 00000000000..02f244ed22e --- /dev/null +++ b/utils/build/ssi/base/healthcheck.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if [ -z "${WEBLOG_URL-}" ]; then + WEBLOG_URL="http://localhost:18080" +fi + +curl --fail --silent --show-error "${WEBLOG_URL}" diff --git a/utils/build/ssi/base/install_os_deps.sh b/utils/build/ssi/base/install_os_deps.sh new file mode 100755 index 00000000000..dac1de1db9c --- /dev/null +++ b/utils/build/ssi/base/install_os_deps.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +declare -r ARCH="$1" + +if [[ "$(cat /etc/redhat-release || true)" == "Red Hat Enterprise Linux release 8."* ]]; then + OS="RedHat_8" +elif [[ "$(cat /etc/redhat-release || true)" == "Red Hat Enterprise Linux release 9."* ]]; then + OS="RedHat_9" +elif [[ "$(cat /etc/redhat-release || true)" == "AlmaLinux release"* ]]; then + OS="RedHat_9" +elif [[ "$(cat /etc/redhat-release || true)" == "CentOS Linux release 7.8.2003 (Core)" ]]; then + OS="RedHat_Centos_7_8" +elif [ -f /etc/debian_version ] || [ "$DISTRIBUTION" = "Debian" ] || [ "$DISTRIBUTION" = "Ubuntu" ]; then + OS="Debian" +elif [ -f /etc/redhat-release ] || [ "$DISTRIBUTION" = "RedHat" ] || [ "$DISTRIBUTION" = "CentOS" ] || [ "$DISTRIBUTION" = "Amazon" ] || [ "$DISTRIBUTION" = "Rocky" ] || [ "$DISTRIBUTION" = "AlmaLinux" ]; then + OS="RedHat" +# Some newer distros like Amazon may not have a redhat-release file +elif [ -f /etc/system-release ] || [ "$DISTRIBUTION" = "Amazon" ]; then + OS="RedHat" +# Arista is based off of Fedora14/18 but do not have /etc/redhat-release +elif [ -f /etc/Eos-release ] || [ "$DISTRIBUTION" = "Arista" ]; then + OS="RedHat" +# openSUSE and SUSE use /etc/SuSE-release or /etc/os-release +elif [ -f /etc/SuSE-release ] || [ "$DISTRIBUTION" = "SUSE" ] || [ "$DISTRIBUTION" = "openSUSE" ]; then + OS="SUSE" +elif [ -f /etc/alpine-release ]; then + OS="Alpine" +fi +echo "SELECTED OS: $OS" +if [ "$OS" = "RedHat_8" ] || [ "$OS" = "RedHat_9" ]; then + if ! command -v yum &> /dev/null + then + microdnf install -y yum + fi + yum install -y which zip unzip wget +elif [ "$OS" = "RedHat_Centos_7_8" ]; then + sed -i.bak 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* + sed -i.bak 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* + yum install -y which zip unzip wget +elif [ "$OS" = "RedHat" ]; then + # Update the repo URLs, since July 2024 we need to use vault for CentOS 7 + if [ "${ARCH}" != "amd64" ]; then + repo_version="altarch/7.9.2009" + else + repo_version="7.9.2009" + fi + + cat << EOF > /etc/yum.repos.d/CentOS-Base.repo +[base] +name=CentOS-\$releasever - Base +baseurl=http://vault.centos.org/${repo_version}/os/\$basearch/ +gpgcheck=0 + +[updates] +name=CentOS-\$releasever - Updates +baseurl=http://vault.centos.org/${repo_version}/updates/\$basearch/ +gpgcheck=0 + +[extras] +name=CentOS-\$releasever - Extras +baseurl=http://vault.centos.org/${repo_version}/extras/\$basearch/ +gpgcheck=0 + +[centosplus] +name=CentOS-\$releasever - Plus +baseurl=http://vault.centos.org/${repo_version}/centosplus/\$basearch/ +gpgcheck=0 +enabled=0 +EOF + yum install -y which zip unzip wget +elif [ "$OS" = "Debian" ]; then + export DEBIAN_FRONTEND=noninteractive + apt-get update + apt-get install --yes curl zip unzip wget git software-properties-common php-cli +elif [ "$OS" = "Alpine" ]; then + apk add -U curl bash +else + echo "Unknown OS" + exit 1 +fi diff --git a/utils/build/ssi/base/install_script_ssi.sh b/utils/build/ssi/base/install_script_ssi.sh new file mode 100755 index 00000000000..34c02858a7b --- /dev/null +++ b/utils/build/ssi/base/install_script_ssi.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +DD_INSTALL_ONLY=true DD_APM_INSTRUMENTATION_ENABLED=host bash -c "$(curl -L https://s3.amazonaws.com/dd-agent/scripts/install_script_agent7.sh)" + +if [ -f /etc/debian_version ] || [ "$DISTRIBUTION" == "Debian" ] || [ "$DISTRIBUTION" == "Ubuntu" ]; then + OS="Debian" +elif [ -f /etc/redhat-release ] || [ "$DISTRIBUTION" == "RedHat" ] || [ "$DISTRIBUTION" == "CentOS" ] || [ "$DISTRIBUTION" == "Amazon" ] || [ "$DISTRIBUTION" == "Rocky" ] || [ "$DISTRIBUTION" == "AlmaLinux" ]; then + OS="RedHat" +# Some newer distros like Amazon may not have a redhat-release file +elif [ -f /etc/system-release ] || [ "$DISTRIBUTION" == "Amazon" ]; then + OS="RedHat" +# Arista is based off of Fedora14/18 but do not have /etc/redhat-release +elif [ -f /etc/Eos-release ] || [ "$DISTRIBUTION" == "Arista" ]; then + OS="RedHat" +# openSUSE and SUSE use /etc/SuSE-release or /etc/os-release +elif [ -f /etc/SuSE-release ] || [ "$DISTRIBUTION" == "SUSE" ] || [ "$DISTRIBUTION" == "openSUSE" ]; then + OS="SUSE" +fi + +# Not needed since we use the test agent, this only makes the image bigger +if [ "$OS" == "RedHat" ]; then + yum erase --assumeyes datadog-agent +elif [ "$OS" == "Debian" ]; then + apt-get remove --yes datadog-agent +fi diff --git a/utils/build/ssi/base/install_script_ssi_installer.sh b/utils/build/ssi/base/install_script_ssi_installer.sh new file mode 100755 index 00000000000..f788951f67d --- /dev/null +++ b/utils/build/ssi/base/install_script_ssi_installer.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +DD_INSTALL_ONLY=true DD_INSTALLER=true bash -c "$(curl -L https://s3.amazonaws.com/dd-agent/scripts/install_script_agent7.sh)" diff --git a/utils/build/ssi/base/java_install_runtimes.sh b/utils/build/ssi/base/java_install_runtimes.sh new file mode 100755 index 00000000000..9700e58511f --- /dev/null +++ b/utils/build/ssi/base/java_install_runtimes.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e + +declare -r RUNTIME_VERSIONS="$1" + +sleep $((1 + RANDOM % 20)) # Sleep a random 1-20 seconds to avoid sdkman rate limits + +curl -s "https://get.sdkman.io" | bash +# shellcheck source=/dev/null +source "/root/.sdkman/bin/sdkman-init.sh" +sed -i -e 's/sdkman_auto_answer=false/sdkman_auto_answer=true/g' /root/.sdkman/etc/config + +for VERSION in $(echo "$RUNTIME_VERSIONS" | tr ',' ' '); do + sleep $((1 + RANDOM % 10)) # Sleep a random 1-10 seconds to avoid sdkman rate limits + sdk install java "$VERSION" +done + +ln -s "${SDKMAN_DIR}/candidates/java/current/bin/java" /usr/bin/java +ln -s "${SDKMAN_DIR}/candidates/java/current/bin/javac" /usr/bin/javac \ No newline at end of file diff --git a/utils/build/ssi/base/js_install_runtimes.sh b/utils/build/ssi/base/js_install_runtimes.sh new file mode 100755 index 00000000000..15268247ae2 --- /dev/null +++ b/utils/build/ssi/base/js_install_runtimes.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# shellcheck disable=SC1091 + +export NODEJS_VERSION=$1 + +if [ -f /etc/debian_version ] || [ "$DISTRIBUTION" = "Debian" ] || [ "$DISTRIBUTION" = "Ubuntu" ]; then + OS="Debian" +elif [ -f /etc/redhat-release ] || [ "$DISTRIBUTION" = "RedHat" ] || [ "$DISTRIBUTION" = "CentOS" ] || [ "$DISTRIBUTION" = "Amazon" ] || [ "$DISTRIBUTION" = "Rocky" ] || [ "$DISTRIBUTION" = "AlmaLinux" ]; then + OS="RedHat" +elif [ -f /etc/system-release ] || [ "$DISTRIBUTION" = "Amazon" ]; then + OS="RedHat" +elif [ -f /etc/Eos-release ] || [ "$DISTRIBUTION" = "Arista" ]; then + OS="RedHat" +elif [ -f /etc/SuSE-release ] || [ "$DISTRIBUTION" = "SUSE" ] || [ "$DISTRIBUTION" = "openSUSE" ]; then + OS="SUSE" +elif [ -f /etc/alpine-release ]; then + OS="Alpine" +fi + +if [ "$OS" = "Debian" ]; then + apt-get update + ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git curl +elif [ "$OS" = "RedHat" ]; then + yum install -y git curl +else + echo "Unknown OS" + exit 1 +fi + +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash +export NVM_DIR="/root/.nvm" +. "$NVM_DIR/nvm.sh" +nvm install "${NODEJS_VERSION}" +nvm alias default "${NODEJS_VERSION}" +node --version diff --git a/utils/build/ssi/base/php_install_runtimes.sh b/utils/build/ssi/base/php_install_runtimes.sh new file mode 100755 index 00000000000..bd6dfe249bd --- /dev/null +++ b/utils/build/ssi/base/php_install_runtimes.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +export PHP_VERSION=$1 + +if [ -f /etc/debian_version ] || [ "$DISTRIBUTION" = "Debian" ] || [ "$DISTRIBUTION" = "Ubuntu" ]; then + OS="Debian" +elif [ -f /etc/redhat-release ] || [ "$DISTRIBUTION" = "RedHat" ] || [ "$DISTRIBUTION" = "CentOS" ] || [ "$DISTRIBUTION" = "Amazon" ] || [ "$DISTRIBUTION" = "Rocky" ] || [ "$DISTRIBUTION" = "AlmaLinux" ]; then + OS="RedHat" +elif [ -f /etc/system-release ] || [ "$DISTRIBUTION" = "Amazon" ]; then + OS="RedHat" +elif [ -f /etc/Eos-release ] || [ "$DISTRIBUTION" = "Arista" ]; then + OS="RedHat" +elif [ -f /etc/SuSE-release ] || [ "$DISTRIBUTION" = "SUSE" ] || [ "$DISTRIBUTION" = "openSUSE" ]; then + OS="SUSE" +elif [ -f /etc/alpine-release ]; then + OS="Alpine" +fi + +if [ "$OS" = "Debian" ]; then + export DEBIAN_FRONTEND=noninteractive + + # Remove the PHP installed in install_os_deps.sh + apt remove --yes php-cli + apt autoremove --yes + + # FIXME: Debian + #curl -sSL https://packages.sury.org/php/README.txt | sudo bash -x + + # Ubuntu + LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php + apt update + + apt install --yes "php${PHP_VERSION}-cli" + + # Hack! + # The requirements.json file provided by PHP prevents PHP 5 from being injected. + # To be able to test the "library_entrypoint.abort" telemetry, we have to change the path. + if [[ "${PHP_VERSION}" == "5.6" ]]; then + rm -f /usr/bin/php + mv /usr/bin/php5.6 /usr/bin/php + fi + + php -v + +elif [ "$OS" = "RedHat" ]; then + yum install -y php +else + echo "Unknown OS" + exit 1 +fi diff --git a/utils/build/ssi/base/python_install_runtimes.sh b/utils/build/ssi/base/python_install_runtimes.sh new file mode 100755 index 00000000000..c2af3b85952 --- /dev/null +++ b/utils/build/ssi/base/python_install_runtimes.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +export PY_VERSION=$1 + +if [ -f /etc/debian_version ] || [ "$DISTRIBUTION" = "Debian" ] || [ "$DISTRIBUTION" = "Ubuntu" ]; then + OS="Debian" +elif [ -f /etc/redhat-release ] || [ "$DISTRIBUTION" = "RedHat" ] || [ "$DISTRIBUTION" = "CentOS" ] || [ "$DISTRIBUTION" = "Amazon" ] || [ "$DISTRIBUTION" = "Rocky" ] || [ "$DISTRIBUTION" = "AlmaLinux" ]; then + OS="RedHat" +elif [ -f /etc/system-release ] || [ "$DISTRIBUTION" = "Amazon" ]; then + OS="RedHat" +elif [ -f /etc/Eos-release ] || [ "$DISTRIBUTION" = "Arista" ]; then + OS="RedHat" +elif [ -f /etc/SuSE-release ] || [ "$DISTRIBUTION" = "SUSE" ] || [ "$DISTRIBUTION" = "openSUSE" ]; then + OS="SUSE" +elif [ -f /etc/alpine-release ]; then + OS="Alpine" +fi + +if [ "$OS" = "Debian" ]; then + apt-get update + ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev git curl llvm libncursesw5-dev xz-utils tk-dev tzdata libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev + curl https://pyenv.run | bash + PYENV_ROOT="$HOME/.pyenv" + PATH="$PYENV_ROOT/bin:$PATH" + eval "$(pyenv init -)" + pyenv install "$PY_VERSION" + pyenv global "$PY_VERSION" +elif [ "$OS" = "RedHat" ]; then + yum install -y python3 +else + echo "Unknown OS" + exit 1 +fi diff --git a/utils/build/ssi/base/tested_components.sh b/utils/build/ssi/base/tested_components.sh new file mode 100755 index 00000000000..ee3b2b73d7b --- /dev/null +++ b/utils/build/ssi/base/tested_components.sh @@ -0,0 +1,97 @@ +#!/bin/bash +# shellcheck disable=SC2116,SC2086,SC1091 + +export DD_APM_INSTRUMENTATION_DEBUG=false +DD_LANG=$1 + +if [ "$DD_LANG" == "java" ]; then + java_version=$(java -version 2>&1) + runtime_version=$(echo "$java_version" | grep version | awk '{print $3}' | tr -d '"') +elif [ "$DD_LANG" == "php" ]; then + runtime_version=$(php -v | grep -oP 'PHP \K[0-9]+\.[0-9]+\.[0-9]+') +elif [ "$DD_LANG" == "python" ]; then + runtime_version=$(python --version | grep -oP 'Python \K[0-9]+\.[0-9]+\.[0-9]+') +elif [ "$DD_LANG" == "js" ]; then + export NVM_DIR="/root/.nvm" + . "$NVM_DIR/nvm.sh" + + runtime_version=$(node --version | tr -d 'v') +elif [ "$DD_LANG" == "dotnet" ]; then + runtime_version=$(dotnet --version) +fi + +if [ -f /etc/debian_version ] || [ "$DISTRIBUTION" = "Debian" ] || [ "$DISTRIBUTION" = "Ubuntu" ]; then + if dpkg -s datadog-agent &> /dev/null; then + agent_version=$(dpkg -s datadog-agent | grep Version | head -n 1); + agent_version=${agent_version//'Version:'/} + else + agent_path="$(readlink -f /opt/datadog-packages/datadog-agent/stable)" + agent_path="${agent_path%/}" + agent_version="${agent_path##*/}" + agent_version="${agent_version%-1}" + fi + + if dpkg -s datadog-apm-inject &> /dev/null; then + inject_version=$(dpkg -s datadog-apm-inject | grep Version); + inject_version=${inject_version//'Version:'/} + else + inject_path="$(readlink -f /opt/datadog-packages/datadog-apm-inject/stable)" + inject_path="${inject_path%/}" + inject_version="${inject_path##*/}" + inject_version="${inject_version%-1}" + fi + + if dpkg -s datadog-apm-library-$DD_LANG &> /dev/null; then + tracer_version=$(dpkg -s datadog-apm-library-$DD_LANG | grep Version); + tracer_version=${tracer_version//'Version:'/} + else + tracer_path="$(readlink -f /opt/datadog-packages/datadog-apm-library-$DD_LANG/stable)" + tracer_path="${tracer_path%/}" + tracer_version="${tracer_path##*/}" + tracer_version="${tracer_version%-1}" + fi + + installer_path="$(readlink -f /opt/datadog-packages/datadog-installer/stable)" + installer_path="${installer_path%/}" + installer_version="${installer_path##*/}" + installer_version="${installer_version%-1}" + + echo "{'weblog_url':'$(echo $WEBLOG_URL)','runtime_version':'$(echo $runtime_version)','agent':'$(echo $agent_version)','datadog-apm-inject':'$(echo $inject_version)','datadog-apm-library-$DD_LANG': '$(echo $tracer_version)','docker':'$(docker -v || true)','datadog-installer':'$(echo $installer_version)'}" + +elif [ -f /etc/redhat-release ] || [ "$DISTRIBUTION" = "RedHat" ] || [ "$DISTRIBUTION" = "CentOS" ] || [ "$DISTRIBUTION" = "Amazon" ] || [ "$DISTRIBUTION" = "Rocky" ] || [ "$DISTRIBUTION" = "AlmaLinux" ]; then + if [ -n "$(rpm -qa --queryformat '%{VERSION}-%{RELEASE}' datadog-agent)" ]; then + agent_version=$(rpm -qa --queryformat '%{VERSION}-%{RELEASE}' datadog-agent); + else + agent_path="$(readlink -f /opt/datadog-packages/datadog-agent/stable)" + agent_path="${agent_path%/}" + agent_version="${agent_path##*/}" + agent_version="${agent_version%-1}" + fi + + if [ -n "$(rpm -qa --queryformat '%{VERSION}-%{RELEASE}' datadog-apm-inject)" ]; then + inject_version=$(rpm -qa --queryformat '%{VERSION}-%{RELEASE}' datadog-apm-inject); + else + inject_path="$(readlink -f /opt/datadog-packages/datadog-apm-inject/stable)" + inject_path="${inject_path%/}" + inject_version="${inject_path##*/}" + inject_version="${inject_version%-1}" + fi + + if [ -n "$(rpm -qa --queryformat '%{VERSION}-%{RELEASE}' datadog-apm-library-$DD_LANG)" ]; then + tracer_version=$(rpm -qa --queryformat '%{VERSION}-%{RELEASE}' datadog-apm-library-$DD_LANG); + else + tracer_path="$(readlink -f /opt/datadog-packages/datadog-apm-library-$DD_LANG/stable)" + tracer_path="${tracer_path%/}" + tracer_version="${tracer_path##*/}" + tracer_version="${tracer_version%-1}" + fi + + installer_path="$(readlink -f /opt/datadog-packages/datadog-installer/stable)" + installer_path="${installer_path%/}" + installer_version="${installer_path##*/}" + installer_version="${installer_version%-1}" + + echo "{'weblog_url':'$(echo $WEBLOG_URL)','runtime_version':'$(echo $runtime_version)','agent':'$(echo $agent_version)','datadog-apm-inject':'$(echo $inject_version)','datadog-apm-library-$DD_LANG': '$(echo $tracer_version)','docker':'$(docker -v || true)','datadog-installer':'$(echo $installer_version)'}" +else + echo "NO_SUPPORTED" +fi diff --git a/utils/build/ssi/build_local_manual.sh b/utils/build/ssi/build_local_manual.sh new file mode 100755 index 00000000000..11664f40ce1 --- /dev/null +++ b/utils/build/ssi/build_local_manual.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash + +#This script allows to build and run Docker SSI images for weblog variants to test different features of SSI. +#This script creates the test matrix (weblog variants, base images, archs, installable runtimes) and runs the tests for each combination. + +set -e + +BASE_DIR=$(pwd) + +print_usage() { + echo -e "${WHITE_BOLD}DESCRIPTION${NC}" + echo -e " Builds and run Docker SSI images for weblog variants to test different features of SSI." + echo + echo -e "${WHITE_BOLD}USAGE${NC}" + echo -e " ${SCRIPT_NAME} [options...]" + echo + echo -e "${WHITE_BOLD}OPTIONS${NC}" + echo -e " ${CYAN}--library ${NC} Language of the tracer (env: TEST_LIBRARY, default: ${DEFAULT_TEST_LIBRARY})." + echo -e " ${CYAN}--weblog-variant ${NC} Weblog variant (env: WEBLOG_VARIANT)." + echo -e " ${CYAN}--arch${NC} Build docker image architecture (env: ARCH)." + echo -e " ${CYAN}--force-build${NC} Force the image build (not use the ghcr images)." + echo -e " ${CYAN}--push-base-images${NC} Push the base images to the registry." + echo -e " ${CYAN}--help${NC} Prints this message and exits." + echo + echo -e "${WHITE_BOLD}EXAMPLES${NC}" + echo -e " Build and run all java-app weblog combinations" + echo -e " utils/build/ssi/build_local.sh java -w java-app " + echo -e " Build and run all java-app weblog combinations for arm64 arch:" + echo -e " utils/build/ssi/build_local.sh java -w java-app -a linux/arm64" + echo -e " Force build and run all java-app weblog combinations for arm64 arch:" + echo -e " utils/build/ssi/build_local.sh java -w java-app -a linux/arm64 --force-build true" + echo +} + + +while [[ "$#" -gt 0 ]]; do + case $1 in + dotnet|java|nodejs|php|python|ruby) TEST_LIBRARY="$1";; + -l|--library) TEST_LIBRARY="$2"; shift ;; + -r|--installable-runtime) INSTALLABLE_RUNTIME="$2"; shift ;; + -w|--weblog-variant) WEBLOG_VARIANT="$2"; shift ;; + -a|--arch) ARCH="$2"; shift ;; + -f|--force-build) FORCE_BUILD="$2"; shift ;; + -p|--push-base-images) PUSH_BASE_IMAGES="$2"; shift ;; + -h|--help) print_usage; exit 0 ;; + *) echo "Invalid argument: ${1:-}"; echo; print_usage; exit 1 ;; + esac + shift +done + +cd "${BASE_DIR}" || exit +matrix_json=$(python utils/docker_ssi/docker_ssi_matrix_builder.py --format json) + +extra_args="" +if [ -n "$FORCE_BUILD" ]; then + extra_args="--ssi-force-build" +fi +if [ -n "$PUSH_BASE_IMAGES" ]; then + extra_args="--ssi-push-base-images" +fi + +while read -r row +do + weblog=$(echo "$row" | jq -r .weblog) + base_image=$(echo "$row" | jq -r .base_image) + arch=$(echo "$row" | jq -r .arch) + installable_runtime=$(echo "$row" | jq -r .installable_runtime) + if [ -n "$INSTALLABLE_RUNTIME" ] && [ "$INSTALLABLE_RUNTIME" != "$installable_runtime" ]; then + continue + fi + if [ -n "$WEBLOG_VARIANT" ] && [ "$WEBLOG_VARIANT" != "$weblog" ]; then + continue + fi + if [ -n "$ARCH" ] && [ "$ARCH" != "$arch" ]; then + continue + fi + + echo "Runing test scenario for weblog [${weblog}], base_image [${base_image}], arch [${arch}], installable_runtime [${installable_runtime}], extra_args: [${extra_args}]" + ./run.sh DOCKER_SSI --ssi-weblog "$weblog" --ssi-library "$TEST_LIBRARY" --ssi-base-image "$base_image" --ssi-arch "$arch" --ssi-installable-runtime "$installable_runtime" "$extra_args" + +done < <(echo "$matrix_json" | jq -c ".${TEST_LIBRARY}.parallel.matrix[]") diff --git a/utils/build/ssi/build_local_wizard.sh b/utils/build/ssi/build_local_wizard.sh new file mode 100755 index 00000000000..806b3c26ac7 --- /dev/null +++ b/utils/build/ssi/build_local_wizard.sh @@ -0,0 +1,122 @@ +#!/bin/bash +# shellcheck disable=SC2207,SC2162,SC2206 + +# Path to the JSON file +JSON_FILE="/tmp/matrix.json" +python utils/docker_ssi/docker_ssi_matrix_builder.py --format json > $JSON_FILE + +# Function to get libraries that extend from .base_ssi_job +get_libraries() { + jq -r 'keys[] | select(. != "stages" and . != "configure" and . != ".base_ssi_job")' "$JSON_FILE" +} + +# Function to get available weblogs for a specific library +get_weblogs() { + local library=$1 + jq -r ".[\"${library}\"].parallel.matrix | map(.weblog) | unique | .[]" "$JSON_FILE" +} + +# Function to get available base images for a specific weblog +get_base_images() { + local library=$1 + local selected_weblog=$2 + jq -r ".[\"${library}\"].parallel.matrix | map(select(.weblog == \"${selected_weblog}\")) | map(.base_image) | unique | .[]" "$JSON_FILE" +} + +# Function to get available architectures for a specific weblog and base image +get_architectures() { + local library=$1 + local selected_weblog=$2 + local selected_base_image=$3 + jq -r ".[\"${library}\"].parallel.matrix | map(select(.weblog == \"${selected_weblog}\" and .base_image == \"${selected_base_image}\")) | map(.arch) | unique | .[]" "$JSON_FILE" +} + +# Function to get available installable runtimes for a specific weblog, base image, and architecture +get_installable_runtimes() { + local library=$1 + local selected_weblog=$2 + local selected_base_image=$3 + local selected_arch=$4 + jq -r ".[\"${library}\"].parallel.matrix | map(select(.weblog == \"${selected_weblog}\" and .base_image == \"${selected_base_image}\" and .arch == \"${selected_arch}\")) | map(.installable_runtime) | unique | .[]" "$JSON_FILE" +} + +# Interactive wizard +echo "Welcome to the SSI Wizard!" + +# Step 1: Select the library +libraries=( $(get_libraries) ) +echo "Please select the library you want to test:" +select TEST_LIBRARY in "${libraries[@]}"; do + if [[ -n "$TEST_LIBRARY" ]]; then + echo "You selected: $TEST_LIBRARY" + break + else + echo "Invalid selection. Please try again." + fi +done + +# Step 2: Select the weblog +weblogs=( $(get_weblogs "$TEST_LIBRARY") ) +echo "Please select the weblog you want to use:" +select weblog in "${weblogs[@]}"; do + if [[ -n "$weblog" ]]; then + echo "You selected: $weblog" + break + else + echo "Invalid selection. Please try again." + fi +done + +# Step 3: Select the base image +base_images=( $(get_base_images "$TEST_LIBRARY" "$weblog") ) +echo "Please select the base image you want to use:" +select base_image in "${base_images[@]}"; do + if [[ -n "$base_image" ]]; then + echo "You selected: $base_image" + break + else + echo "Invalid selection. Please try again." + fi +done + +# Step 4: Select the architecture +architectures=( $(get_architectures "$TEST_LIBRARY" "$weblog" "$base_image") ) +echo "Please select the architecture you want to use:" +select arch in "${architectures[@]}"; do + if [[ -n "$arch" ]]; then + echo "You selected: $arch" + break + else + echo "Invalid selection. Please try again." + fi +done + +# Step 5: Select the installable runtime if available +installable_runtimes=( $(get_installable_runtimes "$TEST_LIBRARY" "$weblog" "$base_image" "$arch") ) +if [[ ${#installable_runtimes[@]} -gt 0 ]]; then + echo "Please select the installable runtime you want to use:" + select installable_runtime in "${installable_runtimes[@]}"; do + if [[ -n "$installable_runtime" ]]; then + echo "You selected: $installable_runtime" + break + else + echo "Invalid selection. Please try again." + fi + done +else + echo "No installable runtime available for the selected options." + installable_runtime="" +fi + +# Step 6: Ask for additional parameters +read -p "Enter any extra arguments (or leave blank): " extra_args + +# Step 7: Execute the command +CMD=("./run.sh" "DOCKER_SSI" "--ssi-weblog" "$weblog" "--ssi-library" "$TEST_LIBRARY" "--ssi-base-image" "$base_image" "--ssi-arch" "$arch") +if [[ -n "$installable_runtime" ]]; then + CMD+=("--ssi-installable-runtime" "$installable_runtime") +fi +CMD+=($extra_args) + +echo "Executing: ${CMD[*]}" +"${CMD[@]}" \ No newline at end of file diff --git a/utils/build/ssi/dotnet/dotnet-app.Dockerfile b/utils/build/ssi/dotnet/dotnet-app.Dockerfile new file mode 100644 index 00000000000..f7e2ec0b615 --- /dev/null +++ b/utils/build/ssi/dotnet/dotnet-app.Dockerfile @@ -0,0 +1,15 @@ +ARG BASE_IMAGE + +FROM ${BASE_IMAGE} +WORKDIR /app + +ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 + +COPY lib-injection/build/docker/dotnet/dd-lib-dotnet-init-test-app/ . + +RUN dotnet restore +RUN dotnet build -c Release + +ENV ASPNETCORE_URLS=http://+:18080 +EXPOSE 18080 +CMD [ "dotnet", "run", "--no-build", "--no-restore", "-c", "Release" ] \ No newline at end of file diff --git a/utils/build/ssi/java/java-app.Dockerfile b/utils/build/ssi/java/java-app.Dockerfile new file mode 100644 index 00000000000..e0891d406b8 --- /dev/null +++ b/utils/build/ssi/java/java-app.Dockerfile @@ -0,0 +1,9 @@ +#syntax=docker/dockerfile:1.4 +ARG BASE_IMAGE + +FROM ${BASE_IMAGE} + +COPY lib-injection/build/docker/java/jdk7-app/ . +RUN javac *.java + +CMD [ "java", "-cp", ".", "SimpleHttpServer" ] \ No newline at end of file diff --git a/utils/build/ssi/java/java7-app.Dockerfile b/utils/build/ssi/java/java7-app.Dockerfile new file mode 100644 index 00000000000..7d7ec0a6ccd --- /dev/null +++ b/utils/build/ssi/java/java7-app.Dockerfile @@ -0,0 +1,26 @@ + +# +# OpenJDK Java 7 JDK Dockerfile +# +ARG BASE_IMAGE + +FROM ubuntu:trusty as java7 + +ENV APT_GET_UPDATE 2015-10-29 +RUN apt-get update +RUN DEBIAN_FRONTEND=noninteractive \ + apt-get -q -y install openjdk-7-jdk wget unzip \ + && apt-get clean +ENV JAVA_HOME /usr/lib/jvm/java-7-openjdk-arm64 + + +FROM ${BASE_IMAGE} +WORKDIR /app +RUN apt-get install -y libglib2.0-0 +COPY --from=java7 /usr/lib/jvm /usr/lib/jvm +COPY lib-injection/build/docker/java/jdk7-app/ . +RUN chmod -R 777 /usr/lib/jvm/java-7-openjdk-arm64 +ENV JAVA_HOME /usr/lib/jvm/java-7-openjdk-arm64 +RUN /usr/lib/jvm/java-7-openjdk-arm64/bin/javac *.java +RUN ln -s /usr/lib/jvm/java-7-openjdk-arm64/bin/java /usr/bin/java +CMD [ "java", "-cp", ".", "SimpleHttpServer" ] diff --git a/utils/build/ssi/java/jboss-app.Dockerfile b/utils/build/ssi/java/jboss-app.Dockerfile new file mode 100644 index 00000000000..2387e83a278 --- /dev/null +++ b/utils/build/ssi/java/jboss-app.Dockerfile @@ -0,0 +1,12 @@ +ARG BASE_IMAGE + +FROM maven:3.8.3-jdk-11-slim as build +WORKDIR /app +COPY lib-injection/build/docker/java/enterprise/ ./ +RUN mvn clean package + +FROM ${BASE_IMAGE} +USER jboss +COPY --from=build app/ee-app-ear/target/ee-app.ear /opt/jboss/wildfly/standalone/deployments/ +ENV WEBLOG_URL=http://localhost:8080/payment-service/ +ENV DD_APM_INSTRUMENTATION_DEBUG=true \ No newline at end of file diff --git a/utils/build/ssi/java/jetty-app.Dockerfile b/utils/build/ssi/java/jetty-app.Dockerfile new file mode 100644 index 00000000000..6449cca55ee --- /dev/null +++ b/utils/build/ssi/java/jetty-app.Dockerfile @@ -0,0 +1,18 @@ +#syntax=docker/dockerfile:1.4 +ARG BASE_IMAGE + +FROM ${BASE_IMAGE} + +RUN wget https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-distribution/9.4.56.v20240826/jetty-distribution-9.4.56.v20240826.tar.gz +RUN tar -xvf jetty-distribution-9.4.56.v20240826.tar.gz + +RUN mkdir -p jetty-classpath +RUN find jetty-distribution-9.4.56.v20240826/lib -iname '*.jar' -exec cp \{\} jetty-classpath/ \; + +# Causes ClassNotFound exceptions https://github.com/jetty/jetty.project/issues/4746 +RUN rm jetty-classpath/jetty-jaspi* + +COPY lib-injection/build/docker/java/jetty-app/ . +RUN javac -cp "jetty-classpath/*" JettyServletMain.java CrashServlet.java + +CMD [ "java", "-cp", "jetty-classpath/*:.", "JettyServletMain" ] diff --git a/utils/build/ssi/java/resources/common/netstat.sh b/utils/build/ssi/java/resources/common/netstat.sh new file mode 100755 index 00000000000..edc66629075 --- /dev/null +++ b/utils/build/ssi/java/resources/common/netstat.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +awk 'function hextodec(str,ret,n,i,k,c){ + ret = 0 + n = length(str) + for (i = 1; i <= n; i++) { + c = tolower(substr(str, i, 1)) + k = index("123456789abcdef", c) + ret = ret * 16 + k + } + return ret +} +function getIP(str,ret){ + ret=hextodec(substr(str,index(str,":")-2,2)); + for (i=5; i>0; i-=2) { + ret = ret"."hextodec(substr(str,i,2)) + } + ret = ret":"hextodec(substr(str,index(str,":")+1,4)) + return ret +} +NR > 1 {{if(NR==2)print "Local - Remote";local=getIP($2);remote=getIP($3)}{print local" - "remote}}' /proc/net/tcp /proc/net/tcp6 \ No newline at end of file diff --git a/utils/build/ssi/java/resources/websphere-app/ws_deploy.jacl b/utils/build/ssi/java/resources/websphere-app/ws_deploy.jacl new file mode 100644 index 00000000000..1bb8e76ef4d --- /dev/null +++ b/utils/build/ssi/java/resources/websphere-app/ws_deploy.jacl @@ -0,0 +1,5 @@ +$AdminApp install "/tmp/ee-app.ear" {-usedefaultbindings} +set appManager [$AdminControl queryNames type=ApplicationManager,process=server1,*] +$AdminConfig save +$AdminControl invoke $appManager startApplication ee-app-ear +$AdminConfig save diff --git a/utils/build/ssi/java/tomcat-app.Dockerfile b/utils/build/ssi/java/tomcat-app.Dockerfile new file mode 100644 index 00000000000..4c2b07f0abe --- /dev/null +++ b/utils/build/ssi/java/tomcat-app.Dockerfile @@ -0,0 +1,11 @@ +ARG BASE_IMAGE + +FROM maven:3.5.3-jdk-8-alpine as build +WORKDIR /app +COPY lib-injection/build/docker/java/enterprise/ ./ +RUN mvn clean package + +FROM ${BASE_IMAGE} +COPY --from=build app/payment-service/target/payment-service*.war /usr/local/tomcat/webapps/ +ENV WEBLOG_URL=http://localhost:8080/payment-service/ +ENV DD_INSTRUMENT_SERVICE_WITH_APM=true \ No newline at end of file diff --git a/utils/build/ssi/java/websphere-app.Dockerfile b/utils/build/ssi/java/websphere-app.Dockerfile new file mode 100644 index 00000000000..cc076d84868 --- /dev/null +++ b/utils/build/ssi/java/websphere-app.Dockerfile @@ -0,0 +1,19 @@ +ARG BASE_IMAGE + +FROM maven:3.5.3-jdk-8-alpine as build +WORKDIR /app +COPY lib-injection/build/docker/java/enterprise/ ./ +RUN mvn clean package + + +FROM ${BASE_IMAGE} +RUN ln -s /opt/IBM/WebSphere/AppServer/java/8.0/bin/java /usr/bin/java +COPY --from=build app/ee-app-ear/target/ee-app.ear /tmp/ +COPY utils/build/ssi/java/resources/common/netstat.sh /tmp/ +COPY utils/build/ssi/java/resources/websphere-app/ws_deploy.jacl /tmp/ +RUN /bin/bash -c '/work/start_server.sh &' && \ +/bin/bash -c 'while ! /tmp/netstat.sh | grep ":9043"; do sleep 1; done' && \ +/bin/bash -c 'yes | /opt/IBM/WebSphere/AppServer/bin/wsadmin.sh -f /tmp/ws_deploy.jacl -user wsadmin -password $(cat /tmp/PASSWORD) -lang jacl' && \ +/bin/bash -c '/opt/IBM/WebSphere/AppServer/bin/stopServer.sh server1 -user wsadmin -password $(cat /tmp/PASSWORD)' +ENV WEBLOG_URL=http://localhost:9080/payment-service/ +ENV DD_APM_INSTRUMENTATION_DEBUG=true \ No newline at end of file diff --git a/utils/build/ssi/nodejs/js-app.Dockerfile b/utils/build/ssi/nodejs/js-app.Dockerfile new file mode 100644 index 00000000000..5d165371cb8 --- /dev/null +++ b/utils/build/ssi/nodejs/js-app.Dockerfile @@ -0,0 +1,12 @@ +ARG BASE_IMAGE + +FROM ${BASE_IMAGE} +WORKDIR /app +COPY lib-injection/build/docker/nodejs/sample-app/ . +ENV HOME /root +EXPOSE 18080 + +# We need pid 1 to be bash and to properly configure nvm +# doing this via `RUN` doesn't seem to work +COPY utils/build/ssi/nodejs/run.sh /app/ +CMD /app/run.sh diff --git a/utils/build/ssi/nodejs/run.sh b/utils/build/ssi/nodejs/run.sh new file mode 100755 index 00000000000..dadff580da0 --- /dev/null +++ b/utils/build/ssi/nodejs/run.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# shellcheck disable=SC1091 + +export NVM_DIR="/root/.nvm" +. "$NVM_DIR/nvm.sh" + +node index.js diff --git a/utils/build/ssi/php/php-app.Dockerfile b/utils/build/ssi/php/php-app.Dockerfile new file mode 100644 index 00000000000..bf17184c6bc --- /dev/null +++ b/utils/build/ssi/php/php-app.Dockerfile @@ -0,0 +1,9 @@ +ARG BASE_IMAGE + +FROM ${BASE_IMAGE} +WORKDIR /app + +RUN printf " index.php + +# Without the sleep, the docker network has issues +CMD ["sh", "-c", "sleep 2; php -S 0.0.0.0:18080"] diff --git a/utils/build/ssi/python/py-app.Dockerfile b/utils/build/ssi/python/py-app.Dockerfile new file mode 100644 index 00000000000..4c9cbf69c31 --- /dev/null +++ b/utils/build/ssi/python/py-app.Dockerfile @@ -0,0 +1,13 @@ +ARG BASE_IMAGE + +FROM ${BASE_IMAGE} +WORKDIR /app +COPY lib-injection/build/docker/python/dd-lib-python-init-test-django/ . +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +ENV HOME /root +ENV PYENV_ROOT $HOME/.pyenv +ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH +RUN pip install django +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/microvm/microvm_agent_restart_retry.sh b/utils/build/virtual_machine/microvm/microvm_agent_restart_retry.sh index 3fcb00e47da..2090d2ba14e 100755 --- a/utils/build/virtual_machine/microvm/microvm_agent_restart_retry.sh +++ b/utils/build/virtual_machine/microvm/microvm_agent_restart_retry.sh @@ -20,6 +20,9 @@ if [[ $(echo "$RESPONSE" | grep "microvm") ]]; then if [[ $(echo "$RESPONSE_PROCESS" | grep "active (running)") ]] && [[ $(echo "$RESPONSE_TRACE" | grep "active (running)") ]] && [[ $(echo "$RESPONSE_AGENT" | grep "active (running)") ]]; then echo "Agent running OK" break + elif [[ $(echo "$RESPONSE_PROCESS" | grep "is running") ]] && [[ $(echo "$RESPONSE_TRACE" | grep "is running") ]] && [[ $(echo "$RESPONSE_AGENT" | grep "is running") ]]; then + echo "Agent running OK" + break else echo "Agent not running" fi diff --git a/utils/build/virtual_machine/provisions/auto-inject-ld-preload/ld-preload.yml b/utils/build/virtual_machine/provisions/auto-inject-ld-preload/ld-preload.yml new file mode 100644 index 00000000000..aa6e9dd6ba0 --- /dev/null +++ b/utils/build/virtual_machine/provisions/auto-inject-ld-preload/ld-preload.yml @@ -0,0 +1,31 @@ +#Manual installation for lib-injection packages +- os_type: linux + os_distro: deb + + copy_files: + - name: copy-helloworld-cpp + local_path: utils/build/virtual_machine/provisions/auto-inject-ld-preload/main.c + + remote-command: | + echo "Installing gcc" + sudo apt install -y gcc + echo "Compiling main.c to main.so" + gcc -Wall -fPIC -shared -o main.so main.c -ldl + sudo mv main.so /usr/local/lib/ + echo "Adding new data to /etc/ld.so.preload" + sudo bash -c "echo /usr/local/lib/main.so >> /etc/ld.so.preload" + echo "Done" + +- os_type: linux + os_distro: rpm + + copy_files: + - name: copy-helloworld-cpp + local_path: utils/build/virtual_machine/provisions/auto-inject-ld-preload/main.c + + remote-command: | + sudo yum groupinstall "Development Tools" + echo "Compiling main.c to main.so" + gcc -Wall -fPIC -shared -o main.so main.c -ldl + sudo mv main.so /usr/local/lib/ + sudo bash -c "echo /usr/local/lib/main.so >> /etc/ld.so.preload" \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/auto-inject-ld-preload/main.c b/utils/build/virtual_machine/provisions/auto-inject-ld-preload/main.c new file mode 100644 index 00000000000..379789f0a60 --- /dev/null +++ b/utils/build/virtual_machine/provisions/auto-inject-ld-preload/main.c @@ -0,0 +1,12 @@ +#include +#include + +typedef int (*original_puts_t)(const char *str); + +// C program used to add as library in the ld-preload +int puts(const char *str) +{ + original_puts_t original_puts; + original_puts = (original_puts_t) dlsym(RTLD_NEXT,"puts"); + return original_puts(str); +} diff --git a/utils/build/virtual_machine/provisions/auto-inject-ld-preload/provision.yml b/utils/build/virtual_machine/provisions/auto-inject-ld-preload/provision.yml new file mode 100644 index 00000000000..a42f0dad7d0 --- /dev/null +++ b/utils/build/virtual_machine/provisions/auto-inject-ld-preload/provision.yml @@ -0,0 +1,42 @@ +# Optional: Load the environment variables +init-environment: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-environment.yml + +# Mandatory: Scripts to extract the installed/tested components (json {component1:version, component2:version}) +tested_components: + install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-tested_components.yml + +#Optional: Extract the logs from the VM +vm_logs: + install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-vm_logs.yml + +# Mandatory: Steps to provision VM +provision_steps: + - init-config # Init the VM configuration + - prepare-docker # Install docker + - amazon-ecr-credential-helper # Install AWS ECR helper to download images from ECR + - patch-docker-daemon #Patch the docker daemon to avoid networking issues/ip conflicts incident-31160 + - ld-so-preload # Add some staff to the ld.so.preload before install dd software + - install-installer # Install the installer + +init-config: + cache: true + populate_env: false + install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject_init_vm_config.yml + +prepare-docker: + cache: true + install: !include utils/build/virtual_machine/provisions/auto-inject/docker/auto-inject_prepare_docker.yml + +amazon-ecr-credential-helper: + cache: true + install: !include utils/build/virtual_machine/provisions/auto-inject/docker/amazon-ecr-credential-helper.yml + +patch-docker-daemon: + cache: true + install: !include utils/build/virtual_machine/provisions/auto-inject/docker/patch-docker-daemon.yml + +ld-so-preload: + install: !include utils/build/virtual_machine/provisions/auto-inject-ld-preload/ld-preload.yml + +install-installer: + install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject_installer_manual.yml diff --git a/utils/build/virtual_machine/provisions/auto-inject/auto-inject-environment.yml b/utils/build/virtual_machine/provisions/auto-inject/auto-inject-environment.yml index 5454f3b3839..739b05aa925 100644 --- a/utils/build/virtual_machine/provisions/auto-inject/auto-inject-environment.yml +++ b/utils/build/virtual_machine/provisions/auto-inject/auto-inject-environment.yml @@ -5,9 +5,9 @@ agent_major_version: "7" injection_repo_url: datad0g.com injection_dist_channel: beta - injection_major_version: apm deb_repo_name: beta rpm_repo_name: datadog-staging + installer_site: datad0g.com - env: prod agent_repo_url: datadoghq.com @@ -15,6 +15,6 @@ agent_major_version: "7" injection_repo_url: datadoghq.com injection_dist_channel: stable - injection_major_version: "7" deb_repo_name: stable rpm_repo_name: datadog-stable + installer_site: datadoghq.com diff --git a/utils/build/virtual_machine/provisions/auto-inject/auto-inject-prepare_repos.yml b/utils/build/virtual_machine/provisions/auto-inject/auto-inject-prepare_repos.yml deleted file mode 100644 index 949738014a0..00000000000 --- a/utils/build/virtual_machine/provisions/auto-inject/auto-inject-prepare_repos.yml +++ /dev/null @@ -1,46 +0,0 @@ - - os_type: linux - os_distro: deb - remote-command: | - #I have to launch apt-get update before add datadog repositories. - #Problems with Ubuntu 22 if I launch update after add datadog repositories - #Problem executing scripts APT::Update::Post-Invoke-Success 'if /usr/bin/test -w /var/lib/command-not-found/ -a -e /usr/lib/cnf-update-db; then /usr/lib/cnf-update-db > /dev/null; fi' - [[ $(cat /etc/os-release) == *"22.04"* ]] && sudo apt-get update - - #Staging beta repository - sudo echo "deb [signed-by=/usr/share/keyrings/datadog-archive-keyring.gpg] https://apt.datad0g.com beta apm" > datadog-beta.list - - sudo cp datadog-beta.list /etc/apt/sources.list.d/ - #Production repository - sudo echo "deb [signed-by=/usr/share/keyrings/datadog-archive-keyring.gpg] https://apt.datadoghq.com stable 7" > datadog-stable.list - sudo cp datadog-stable.list /etc/apt/sources.list.d/ - #Configure repo keys - sudo touch /usr/share/keyrings/datadog-archive-keyring.gpg - sudo chmod a+r /usr/share/keyrings/datadog-archive-keyring.gpg - - curl https://keys.datadoghq.com/DATADOG_APT_KEY_CURRENT.public | sudo gpg --no-default-keyring --keyring /usr/share/keyrings/datadog-archive-keyring.gpg --import --batch - curl https://keys.datadoghq.com/DATADOG_APT_KEY_382E94DE.public | sudo gpg --no-default-keyring --keyring /usr/share/keyrings/datadog-archive-keyring.gpg --import --batch - curl https://keys.datadoghq.com/DATADOG_APT_KEY_F14F620E.public | sudo gpg --no-default-keyring --keyring /usr/share/keyrings/datadog-archive-keyring.gpg --import --batch - - sudo apt-get update -o Dir::Etc::sourcelist="sources.list.d/datadog-beta.list" -o Dir::Etc::sourceparts="-" -o APT::Get::List-Cleanup="0" || true - sudo apt-get update -o Dir::Etc::sourcelist="sources.list.d/datadog-stable.list" -o Dir::Etc::sourceparts="-" -o APT::Get::List-Cleanup="0" || true - [[ $(cat /etc/os-release) == *"18.04"* ]] && sudo apt-get update - echo "Repositories configured successfully!" - - os_type: linux - os_distro: rpm - copy_files: - - name: copy-datadog-staging-repo.x86_64 - local_path: utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-staging.x86_64.repo - remote_path: datadog-staging.x86_64.repo - - name: copy-datadog-staging-repo.aarch64 - local_path: utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-staging.aarch64.repo - remote_path: datadog-staging.aarch64.repo - - name: copy-datadog-stable-repo.x86_64 - local_path: utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-stable.x86_64.repo - remote_path: datadog-stable.x86_64.repo - - name: copy-datadog-stable-repo.aarch64 - local_path: utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-stable.aarch64.repo - remote_path: datadog-stable.aarch64.repo - - remote-command: | - sudo cp *.$(arch).repo /etc/yum.repos.d/ - sudo yum -y makecache diff --git a/utils/build/virtual_machine/provisions/auto-inject/auto-inject-tested_components.yml b/utils/build/virtual_machine/provisions/auto-inject/auto-inject-tested_components.yml index 7cb26728bc4..8ca6f02444e 100644 --- a/utils/build/virtual_machine/provisions/auto-inject/auto-inject-tested_components.yml +++ b/utils/build/virtual_machine/provisions/auto-inject/auto-inject-tested_components.yml @@ -1,6 +1,9 @@ #Get version of the installed components - os_type: linux os_distro: rpm + copy_files: + - name: copy-glibc-script + local_path: utils/build/virtual_machine/provisions/auto-inject/check_glibc.sh remote-command: | if [ -n "$(rpm -qa --queryformat '%{VERSION}-%{RELEASE}' datadog-agent)" ]; then export agent_version=$(rpm -qa --queryformat '%{VERSION}-%{RELEASE}' datadog-agent); @@ -34,10 +37,29 @@ export installer_version="${installer_path##*/}" export installer_version="${installer_version%-1}" - echo "{'host':'$(hostname -I)','agent':'$(echo $agent_version)','datadog-apm-inject':'$(echo $inject_version)','datadog-apm-library-$DD_LANG': '$(echo $tracer_version)','docker':'$(docker -v || true)','datadog-installer':'$(echo $installer_version)'}" + #Extract glibc + sudo chmod 755 check_glibc.sh + . ./check_glibc.sh + + #Try to extract runtime version. Not allways possible (ie container app) + if [ "$DD_LANG" == "js" ]; then + export runtime_version=$(node -v || echo "v") + runtime_version="${runtime_version:1}" + elif [ "$DD_LANG" == "python" ]; then + export runtime_version=$(python --version 2>&1 | awk '{print $2}' | cut -d '.' -f 1,2) + elif [ "$DD_LANG" == "java" ]; then + export runtime_version=$(java -version 2>&1 | awk 'NR==1{ gsub(/"/,""); print $3 }') + else + export runtime_version="" + fi + + echo "{'host':'$(hostname -I)','agent':'$(echo $agent_version)','datadog-apm-inject':'$(echo $inject_version)','datadog-apm-library-$DD_LANG': '$(echo $tracer_version)','docker':'$(docker -v || true)','datadog-installer':'$(echo $installer_version)','glibc_type':'$(echo $GLIBC_TYPE)','glibc':'$(echo $GLIBC_VERSION)','runtime_version':'$(echo $runtime_version)'}" - os_type: linux os_distro: deb + copy_files: + - name: copy-glibc-script + local_path: utils/build/virtual_machine/provisions/auto-inject/check_glibc.sh remote-command: | if dpkg -s datadog-agent &> /dev/null; then export agent_version=$(dpkg -s datadog-agent | grep Version | head -n 1); @@ -73,5 +95,21 @@ export installer_path="${installer_path%/}" export installer_version="${installer_path##*/}" export installer_version="${installer_version%-1}" + + #Extract glibc + sudo chmod 755 check_glibc.sh + . ./check_glibc.sh + + #Try to extract runtime version. Not allways possible (ie container app) + if [ "$DD_LANG" == "js" ]; then + export runtime_version=$(node -v || echo "v") + runtime_version="${runtime_version:1}" + elif [ "$DD_LANG" == "python" ]; then + export runtime_version=$(python --version 2>&1 | awk '{print $2}' | cut -d '.' -f 1,2) + elif [ "$DD_LANG" == "java" ]; then + export runtime_version=$(java -version 2>&1 | awk 'NR==1{ gsub(/"/,""); print $3 }') + else + export runtime_version="" + fi - echo "{'host':'$(hostname -I)','agent':'$(echo $agent_version)','datadog-apm-inject':'$(echo $inject_version)','datadog-apm-library-$DD_LANG': '$(echo $tracer_version)','docker':'$(docker -v || true)','datadog-installer':'$(echo $installer_version)'}" + echo "{'host':'$(hostname -I)','agent':'$(echo $agent_version)','datadog-apm-inject':'$(echo $inject_version)','datadog-apm-library-$DD_LANG': '$(echo $tracer_version)','docker':'$(docker -v || true)','datadog-installer':'$(echo $installer_version)','glibc_type':'$(echo $GLIBC_TYPE)','glibc':'$(echo $GLIBC_VERSION)','runtime_version':'$(echo $runtime_version)'}" diff --git a/utils/build/virtual_machine/provisions/auto-inject/auto-inject-vm_logs.yml b/utils/build/virtual_machine/provisions/auto-inject/auto-inject-vm_logs.yml new file mode 100644 index 00000000000..cb1f71a2dbd --- /dev/null +++ b/utils/build/virtual_machine/provisions/auto-inject/auto-inject-vm_logs.yml @@ -0,0 +1,6 @@ +#Extract machine logs (only datadog stuff) +- os_type: linux + remote-command: | + #Wait for the app service up to extract the logs (also app logs) + curl --head -X GET --retry 5 --max-time 20 --retry-connrefused --retry-delay 2 http://localhost:5985 + find /var/log -type f -path "/var/log/datadog*" -name "*.log"| xargs sudo tail -n +1 \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/auto-inject/auto-inject_init_vm_config.yml b/utils/build/virtual_machine/provisions/auto-inject/auto-inject_init_vm_config.yml index 87c9a902f96..3588d4650a4 100644 --- a/utils/build/virtual_machine/provisions/auto-inject/auto-inject_init_vm_config.yml +++ b/utils/build/virtual_machine/provisions/auto-inject/auto-inject_init_vm_config.yml @@ -25,6 +25,26 @@ echo "After stop updates. System service apt-daily.service status" sudo systemctl list-units --all apt-daily.service || true + #There are some old machines that need to change the repositories because there are not available anymore + lsb_release=/etc/lsb-release + must_update_repositories="false" + if [ -e "$lsb_release" ]; then + if grep -q 'Ubuntu 21' "$lsb_release"; then + must_update_repositories="true" + elif grep -q 'Ubuntu 23' "$lsb_release"; then + #Why this works for arm machine but not for amd64? + must_update_repositories="true" + fi + fi + if [ "$must_update_repositories" == "true" ]; then + echo "Configuring archive ubuntu repositories" + sudo sed -i -r 's/ports.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list + sudo sed -i -r 's/ubuntu-ports/ubuntu/g' /etc/apt/sources.list + sudo sed -i -r 's/us-east-1.ec2.//g' /etc/apt/sources.list + echo 'apt_preserve_sources_list: true' | sudo tee -a /etc/cloud/cloud.cfg + sudo apt-get update + fi + sudo apt-get -y update #Install some basic tools (microvm doesn't have them by default) @@ -44,9 +64,90 @@ #Allow DD env variables from ssh echo 'AcceptEnv DD_*' | sudo tee -a /etc/ssh/sshd_config - sudo systemctl restart sshd.service || true + sudo systemctl restart sshd.service || sudo systemctl restart ssh.service || true + + #Install git and clone system tests repository + sudo apt-get -y install git wget + git clone https://github.com/DataDog/system-tests.git + echo "DONE" - +- os_type: linux + os_distro: rpm + os_branch: centos_7_amd64 # CentOS override as the mirrors are not available anymore + remote-command: | + sudo sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo + sudo sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sudo sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo + + #Allow DD env variables from ssh + echo 'AcceptEnv DD_*' | sudo tee -a /etc/ssh/sshd_config + sudo id -u datadog &>/dev/null || sudo useradd -m datadog + sudo yum clean expire-cache + #sudo yum -y update + sudo systemctl restart sshd.service + + #Install git and clone system tests repository + sudo yum -y install git wget + git clone https://github.com/DataDog/system-tests.git + +- os_type: linux + os_distro: rpm + os_branch: centos_8_amd64 # CentOS override as the mirrors are not available anymore + remote-command: | + sudo sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo + sudo sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sudo sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo + + #Allow DD env variables from ssh + echo 'AcceptEnv DD_*' | sudo tee -a /etc/ssh/sshd_config + sudo id -u datadog &>/dev/null || sudo useradd -m datadog + sudo yum clean expire-cache + #sudo yum -y update + sudo systemctl restart sshd.service + + #Install git and clone system tests repository + sudo yum -y install git wget + git clone https://github.com/DataDog/system-tests.git + +- os_type: linux + os_distro: rpm + os_branch: oracle_linux + remote-command: | + #Allow DD env variables from ssh + echo 'AcceptEnv DD_*' | sudo tee -a /etc/ssh/sshd_config + sudo id -u datadog &>/dev/null || sudo useradd -m datadog + sudo yum clean expire-cache + #sudo yum -y update + sudo systemctl restart sshd.service + #Install git and clone system tests repository + sudo yum -y install git wget + git clone https://github.com/DataDog/system-tests.git + #We need to access from outside the VM + sudo systemctl stop firewalld + sudo systemctl stop iptables + sudo systemctl disable firewalld + sudo systemctl disable iptables + if [ $? -eq 3 ] + then + echo "Firewall disabled" + exit 0 + fi +- os_type: linux + os_branch: fedora + os_distro: rpm + remote-command: | + # Disable SELinux as it isn't supported by the injector today + sudo setenforce 0 + sudo sed -i 's/enforcing/disabled/g' /etc/selinux/config + # Allow DD env variables from ssh + echo 'AcceptEnv DD_*' | sudo tee -a /etc/ssh/sshd_config + sudo id -u datadog &>/dev/null || sudo useradd -m datadog + sudo yum clean expire-cache + #sudo yum -y update + sudo systemctl restart sshd.service + #Install git and clone system tests repository + sudo yum -y install git wget which + git clone https://github.com/DataDog/system-tests.git - os_type: linux os_distro: rpm remote-command: | @@ -55,4 +156,7 @@ sudo id -u datadog &>/dev/null || sudo useradd -m datadog sudo yum clean expire-cache #sudo yum -y update - sudo systemctl restart sshd.service \ No newline at end of file + sudo systemctl restart sshd.service + #Install git and clone system tests repository + sudo yum -y install git wget + git clone https://github.com/DataDog/system-tests.git diff --git a/utils/build/virtual_machine/provisions/auto-inject/auto-inject_installer_manual.yml b/utils/build/virtual_machine/provisions/auto-inject/auto-inject_installer_manual.yml new file mode 100644 index 00000000000..fbea89c3ae2 --- /dev/null +++ b/utils/build/virtual_machine/provisions/auto-inject/auto-inject_installer_manual.yml @@ -0,0 +1,57 @@ +# Installs the installer package +- os_type: linux + copy_files: + - name: copy-tracer-debug-config + local_path: utils/build/virtual_machine/provisions/auto-inject/tracer_debug/debug_config.yaml + - name: copy-docker-config + local_path: utils/build/virtual_machine/provisions/auto-inject/docker/docker_config.yaml + + remote-command: | + if [ "${DD_env}" == "dev" ]; then + # To force the installer to pull from dev repositories -- agent config is set manually to datadoghq.com + export DD_SITE="datad0g.com" + export DD_INSTALLER_REGISTRY_URL='install.datad0g.com' + else + export DD_SITE="datadoghq.com" + fi + + # Environment variables for the installer + export DD_APM_INSTRUMENTATION_ENABLED=all + export DD_APM_INSTRUMENTATION_LIBRARIES="${DD_LANG}" + export DD_INSTALLER_DEFAULT_PKG_INSTALL_DATADOG_AGENT=true + + if [ -n "${DD_INSTALLER_LIBRARY_VERSION}" ]; then + export "DD_INSTALLER_REGISTRY_URL_APM_LIBRARY_$(echo "$DD_LANG" | tr "[:lower:]" "[:upper:]")_PACKAGE"='installtesting.datad0g.com' + export "DD_INSTALLER_DEFAULT_PKG_VERSION_DATADOG_APM_LIBRARY_$(echo "$DD_LANG" | tr "[:lower:]" "[:upper:]")"="${DD_INSTALLER_LIBRARY_VERSION}" + fi + + if [ -n "${DD_INSTALLER_INJECTOR_VERSION}" ]; then + export DD_INSTALLER_REGISTRY_URL_APM_INJECT_PACKAGE='installtesting.datad0g.com' + export DD_INSTALLER_DEFAULT_PKG_VERSION_DATADOG_APM_INJECT="${DD_INSTALLER_INJECTOR_VERSION}" + fi + + if [ -n "${DD_INSTALLER_AGENT_VERSION}" ]; then + export DD_INSTALLER_REGISTRY_URL_AGENT_PACKAGE='installtesting.datad0g.com' + export DD_INSTALLER_DEFAULT_PKG_VERSION_DATADOG_AGENT="${DD_INSTALLER_AGENT_VERSION}" + fi + + if [ -n "${DD_INSTALLER_INSTALLER_VERSION}" ]; then + export DD_INSTALLER_REGISTRY_URL_INSTALLER_PACKAGE='installtesting.datad0g.com' + export DD_INSTALLER_DEFAULT_PKG_VERSION_DATADOG_INSTALLER="${DD_INSTALLER_INSTALLER_VERSION}" + fi + + # Env variables set on the scenario definition. Write to file and load + SCENARIO_AGENT_ENV="${DD_AGENT_ENV:-''}" + echo "${SCENARIO_AGENT_ENV}" > scenario_agent.env + echo "AGENT VARIABLES CONFIGURED FROM THE SCENARIO:" + cat scenario_agent.env + export $(cat scenario_agent.env | xargs) + + sudo -E sh -c "sudo mkdir -p /etc/datadog-agent && printf \"api_key: ${DD_API_KEY}\nsite: datadoghq.com\n\" > /etc/datadog-agent/datadog.yaml" + DD_REPO_URL=${DD_injection_repo_url} bash -c "$(curl -L https://install.datadoghq.com/scripts/install_script_agent7.sh)" + + sudo cp /tmp/datadog-installer-*.log /var/log/datadog + + sudo mkdir -p /etc/datadog-agent/inject + sudo cp docker_config.yaml /etc/datadog-agent/inject/docker_config.yaml + sudo cp debug_config.yaml /etc/datadog-agent/inject/debug_config.yaml diff --git a/utils/build/virtual_machine/provisions/auto-inject/auto-inject_pre_installer_manual.yml b/utils/build/virtual_machine/provisions/auto-inject/auto-inject_pre_installer_manual.yml new file mode 100644 index 00000000000..0ee70379e02 --- /dev/null +++ b/utils/build/virtual_machine/provisions/auto-inject/auto-inject_pre_installer_manual.yml @@ -0,0 +1,4 @@ +# Installs the installer package (only, no agent no ssi) +#Our goal is to cache the installer and its dependencies, in the next steps (no cached steps) we will get a fresh copy of the installer +- os_type: linux + remote-command: DD_INSTALL_ONLY=true DD_INSTALLER=true bash -c "$(curl -L https://install.datadoghq.com/scripts/install_script_agent7.sh)" \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/auto-inject/check_glibc.sh b/utils/build/virtual_machine/provisions/auto-inject/check_glibc.sh new file mode 100755 index 00000000000..b5fe9e104d8 --- /dev/null +++ b/utils/build/virtual_machine/provisions/auto-inject/check_glibc.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +if ldd --version &>/dev/null; then + # check if is glibc o musl + if ldd --version | grep -i "musl" &>/dev/null; then + # if musl + libc_version=$(musl-gcc -v 2>&1 | grep "musl" | head -n 1 | awk '{print $1 " " $2}') + export GLIBC_TYPE="musl" + export GLIBC_VERSION="$libc_version" + else + # if glibc + libc_version=$(ldd --version | head -n 1 | awk '{print $NF}') + export GLIBC_TYPE="gnu" + export GLIBC_VERSION="$libc_version" + fi +else + echo "The standard C library cannot be determined." + exit 1 +fi \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/auto-inject/docker/amazon-ecr-credential-helper.yml b/utils/build/virtual_machine/provisions/auto-inject/docker/amazon-ecr-credential-helper.yml new file mode 100644 index 00000000000..08e0f98a98a --- /dev/null +++ b/utils/build/virtual_machine/provisions/auto-inject/docker/amazon-ecr-credential-helper.yml @@ -0,0 +1,11 @@ + - os_type: linux + remote-command: | + # Setup authentication to access AWS ECR + sudo curl -fsSL https://amazon-ecr-credential-helper-releases.s3.us-east-2.amazonaws.com/0.9.0/linux-$([[ $(uname -m) == x86_64 ]] && echo "amd64" || echo "arm64")/docker-credential-ecr-login -o /usr/local/bin/docker-credential-ecr-login + sudo chmod +x /usr/local/bin/docker-credential-ecr-login + #Fix redhat + sudo cp /usr/local/bin/docker-credential-ecr-login /usr/bin || true + sudo mkdir -p ~/.docker + echo '{"credHelpers":{"669783387624.dkr.ecr.us-east-1.amazonaws.com": "ecr-login"}}' | sudo tee ~/.docker/config.json + sudo mkdir -p /root/.docker + echo '{"credHelpers":{"669783387624.dkr.ecr.us-east-1.amazonaws.com": "ecr-login"}}' | sudo tee /root/.docker/config.json diff --git a/utils/build/virtual_machine/provisions/auto-inject/docker/auto-inject_prepare_docker.yml b/utils/build/virtual_machine/provisions/auto-inject/docker/auto-inject_prepare_docker.yml index 27fe9de5a53..ddecbcf0010 100644 --- a/utils/build/virtual_machine/provisions/auto-inject/docker/auto-inject_prepare_docker.yml +++ b/utils/build/virtual_machine/provisions/auto-inject/docker/auto-inject_prepare_docker.yml @@ -5,14 +5,15 @@ sudo apt-get update sudo apt-get -y install ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg + curl -fsSL https://download.docker.com/linux/$(grep -E '^ID=' /etc/os-release | cut -c4-)/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg echo \ - "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ + "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/"$(grep -E '^ID=' /etc/os-release | cut -c4-)" \ "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update - sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin + sudo apt-get -y install docker-buildx-plugin || true #Ubuntu 21.04 doesn't have this package sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose && sudo chmod +x /usr/bin/docker-compose && sudo docker-compose --version echo "DOCKER INSTALLED!" #To run Docker without root privileges @@ -22,14 +23,84 @@ - os_type: linux os_distro: rpm os_branch: centos_7_amd64 # CentOS override - remote-command: | - curl -fsSL https://get.docker.com | sudo sh + remote-command: | + curl -fsSL https://get.docker.com -o install-docker.sh + chmod 755 install-docker.sh + sed -i 's/yum config-manager/yum-config-manager/g' install-docker.sh + sudo sh install-docker.sh + sudo systemctl start docker + sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose && sudo chmod +x /usr/bin/docker-compose && sudo docker-compose --version + - os_type: linux + os_distro: rpm + os_branch: centos_8_amd64 # CentOS override + remote-command: | + curl -fsSL https://get.docker.com -o install-docker.sh + chmod 755 install-docker.sh + sed -i 's/yum config-manager/yum-config-manager/g' install-docker.sh + sudo sh install-docker.sh sudo systemctl start docker sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose && sudo chmod +x /usr/bin/docker-compose && sudo docker-compose --version - os_type: linux os_distro: rpm - remote-command: | + os_branch: rhel_7_amd64 # Rhel 7 override + remote-command: | + sudo yum install -y https://vault.centos.org/7.9.2009/extras/x86_64/Packages/container-selinux-2.107-3.el7.noarch.rpm https://vault.centos.org/7.9.2009/extras/x86_64/Packages/slirp4netns-0.4.3-4.el7_8.x86_64.rpm https://vault.centos.org/7.9.2009/extras/x86_64/Packages/fuse3-libs-3.6.1-4.el7.x86_64.rpm https://vault.centos.org/7.9.2009/extras/x86_64/Packages/fuse-overlayfs-0.7.2-6.el7_8.x86_64.rpm https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-rootless-extras-26.1.4-1.el7.x86_64.rpm https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-compose-plugin-2.27.1-1.el7.x86_64.rpm https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-buildx-plugin-0.14.1-1.el7.x86_64.rpm https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-cli-26.1.4-1.el7.x86_64.rpm https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-26.1.4-1.el7.x86_64.rpm https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.6.33-3.1.el7.x86_64.rpm + sudo systemctl start docker + sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose && sudo chmod +x /usr/bin/docker-compose && sudo docker-compose --version + - os_type: linux + os_distro: rpm + os_branch: oracle_linux + remote-command: | + if ! command -v dnf &> /dev/null + then + sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo + sudo yum-config-manager --enable ol7_addons + sudo yum install -y wget + + #Some repositories are broken from OL7, so we need to download the packages manually! + wget https://www.rpmfind.net/linux/almalinux/8.10/AppStream/x86_64/os/Packages/slirp4netns-0.4.2-3.git21fdece.module_el8.5.0+2635+e4386a39.x86_64.rpm + sudo rpm -Uvh slirp4netns-0.4.2-3.git21fdece.module_el8.5.0+2635+e4386a39.x86_64.rpm + + wget http://yum.gunet.gr/repo/OracleLinux/OL7/developer/x86_64/fuse3-libs-3.6.1-4.el7.x86_64.rpm + sudo rpm -Uvh fuse3-libs-3.6.1-4.el7.x86_64.rpm + + wget ftp://ftp.icm.edu.pl/vol/rzm7/linux-centos-vault/7.9.2009/extras/x86_64/Packages/fuse-overlayfs-0.7.2-6.el7_8.x86_64.rpm + sudo rpm -Uvh fuse-overlayfs-0.7.2-6.el7_8.x86_64.rpm + + #We should have all dependencies installed, now install docker + sudo yum install -y docker-ce docker-ce-cli containerd.io + else + sudo dnf remove -y podman buildah + sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo + sudo dnf install -y docker-ce + fi + + sudo systemctl enable docker.service + sudo systemctl start docker.service + sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose && sudo chmod +x /usr/bin/docker-compose && sudo docker-compose --version + - os_type: linux + os_distro: rpm + os_branch: alma_linux + remote-command: | + sudo dnf remove -y podman buildah || true + sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo + sudo dnf install -y docker-ce + sudo systemctl enable docker.service + sudo systemctl start docker.service + sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose && sudo chmod +x /usr/bin/docker-compose && sudo docker-compose --version + - os_type: linux + os_distro: rpm + os_branch: redhat + remote-command: | + sudo yum remove podman buildah -y || true + sudo yum install -y yum-utils + sudo yum-config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo + sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y + sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose && sudo chmod +x /usr/bin/docker-compose && sudo docker-compose --version + - os_type: linux + os_distro: rpm + remote-command: | sudo yum -y install docker sudo systemctl start docker.service sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose && sudo chmod +x /usr/bin/docker-compose && sudo docker-compose --version - \ No newline at end of file + diff --git a/utils/build/virtual_machine/provisions/auto-inject/docker/patch-docker-daemon.yml b/utils/build/virtual_machine/provisions/auto-inject/docker/patch-docker-daemon.yml new file mode 100644 index 00000000000..4982a290a81 --- /dev/null +++ b/utils/build/virtual_machine/provisions/auto-inject/docker/patch-docker-daemon.yml @@ -0,0 +1,4 @@ + - os_type: linux + remote-command: | + # Patch docker daemon to avoid conflicts with ddbuild runners IP + sudo mkdir -p /etc/docker && echo '{"bip": "192.168.16.1/24", "default-address-pools":[{"base":"192.168.32.0/24", "size":24}]}' | sudo tee /etc/docker/daemon.json diff --git a/utils/build/virtual_machine/provisions/auto-inject/repositories/autoinstall/execute_install_script.sh b/utils/build/virtual_machine/provisions/auto-inject/repositories/autoinstall/execute_install_script.sh index 504307d95e7..dc4f6b1fef9 100755 --- a/utils/build/virtual_machine/provisions/auto-inject/repositories/autoinstall/execute_install_script.sh +++ b/utils/build/virtual_machine/provisions/auto-inject/repositories/autoinstall/execute_install_script.sh @@ -1,31 +1,57 @@ #!/bin/bash -#This script is needed only for this reason: https://datadoghq.atlassian.net/browse/AP-2165 +# This script is needed only for this reason: https://datadoghq.atlassian.net/browse/AP-2165 if [ -z "$INSTALLER_URL" ]; then - INSTALLER_URL="https://s3.amazonaws.com/dd-agent/scripts/install_script_agent7.sh" + INSTALLER_URL="https://install.datadoghq.com/scripts/install_script_agent7.sh" fi -curl -L "$INSTALLER_URL" --output install_script_agent7.sh -chmod 755 install_script_agent7.sh +if [ "$DD_APM_INSTRUMENTATION_ENABLED" == "docker" ]; then + # Skip agent installation in container/docker scenarios + export DD_NO_AGENT_INSTALL=true +fi + +# Installer env vars # shellcheck disable=SC2154 -sed "s/\"7\"/\"$DD_injection_major_version\"/g" install_script_agent7.sh > install_script_agent7_autoinject_temp.sh -sed "s/-eq 7/== \"$DD_injection_major_version\"/g" install_script_agent7_autoinject_temp.sh > install_script_agent7_autoinject.sh -chmod 755 install_script_agent7_autoinject.sh - -if [ "$1" == "docker" ]; then - echo "Skipping agent installation in container/docker scenario (Installing only datadog-signing-keys)" - # shellcheck disable=SC2154 - DD_SITE=$DD_injection_repo_url DD_NO_AGENT_INSTALL=true ./install_script_agent7.sh +if [ "${DD_env}" == "dev" ]; then + # To force the installer to pull from dev repositories -- agent config is set manually to datadoghq.com + export DD_SITE="datad0g.com" + export DD_INSTALLER_REGISTRY_URL='install.datad0g.com' +else + export DD_SITE="datadoghq.com" +fi + +# Environment variables for the installer +export DD_APM_INSTRUMENTATION_LIBRARIES="${DD_LANG}" +export DD_INSTALLER_DEFAULT_PKG_INSTALL_DATADOG_AGENT=true + +if [ -n "${DD_INSTALLER_LIBRARY_VERSION}" ]; then + export "DD_INSTALLER_REGISTRY_URL_APM_LIBRARY_$(echo "$DD_LANG" | tr "[:lower:]" "[:upper:]")_PACKAGE"='installtesting.datad0g.com' + export "DD_INSTALLER_DEFAULT_PKG_VERSION_DATADOG_APM_LIBRARY_$(echo "$DD_LANG" | tr "[:lower:]" "[:upper:]")"="${DD_INSTALLER_LIBRARY_VERSION}" +fi + +if [ -n "${DD_INSTALLER_INJECTOR_VERSION}" ]; then + export DD_INSTALLER_REGISTRY_URL_APM_INJECT_PACKAGE='installtesting.datad0g.com' + export DD_INSTALLER_DEFAULT_PKG_VERSION_DATADOG_APM_INJECT="${DD_INSTALLER_INJECTOR_VERSION}" fi + +if [ -n "${DD_INSTALLER_AGENT_VERSION}" ]; then + export DD_INSTALLER_REGISTRY_URL_AGENT_PACKAGE='installtesting.datad0g.com' + export DD_INSTALLER_DEFAULT_PKG_VERSION_DATADOG_AGENT="${DD_INSTALLER_AGENT_VERSION}" +fi + +if [ -n "${DD_INSTALLER_INSTALLER_VERSION}" ]; then + export DD_INSTALLER_REGISTRY_URL_INSTALLER_PACKAGE='installtesting.datad0g.com' + export DD_INSTALLER_DEFAULT_PKG_VERSION_DATADOG_INSTALLER="${DD_INSTALLER_INSTALLER_VERSION}" +fi + +sudo sh -c "sudo mkdir -p /etc/datadog-agent && printf \"api_key: ${DD_API_KEY}\nsite: datadoghq.com\n\" > /etc/datadog-agent/datadog.yaml" + # shellcheck disable=SC2154 -DD_SITE=$DD_injection_repo_url \ -DD_REPO_URL=$DD_injection_repo_url \ -DD_AGENT_DIST_CHANNEL=$DD_injection_dist_channel \ -DD_AGENT_MAJOR_VERSION=$DD_injection_major_version \ +DD_REPO_URL="$DD_injection_repo_url" \ DD_APM_INSTRUMENTATION_LANGUAGES="$DD_LANG" \ -DD_APM_INSTRUMENTATION_ENABLED="$DD_APM_INSTRUMENTATION_ENABLED" \ -DD_PROFILING_ENABLED="$DD_PROFILING_ENABLED" \ -./install_script_agent7_autoinject.sh +bash -c "$(curl -L "$INSTALLER_URL")" + +sudo cp /tmp/datadog-installer-*.log /var/log/datadog echo "lib-injection install done" diff --git a/utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-stable.aarch64.repo b/utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-stable.aarch64.repo deleted file mode 100644 index f57035d126d..00000000000 --- a/utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-stable.aarch64.repo +++ /dev/null @@ -1,5 +0,0 @@ -[datadog-stable] -baseurl=https://yum.datadoghq.com/stable/7/aarch64/ -gpgcheck=1 -repo_gpgcheck=1 -gpgkey=https://s3.amazonaws.com/public-signing-keys/DATADOG_RPM_KEY_CURRENT.public \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-stable.x86_64.repo b/utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-stable.x86_64.repo deleted file mode 100644 index e179000b441..00000000000 --- a/utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-stable.x86_64.repo +++ /dev/null @@ -1,5 +0,0 @@ -[datadog-stable] -baseurl=https://yum.datadoghq.com/stable/7/x86_64/ -gpgcheck=1 -repo_gpgcheck=1 -gpgkey=https://s3.amazonaws.com/public-signing-keys/DATADOG_RPM_KEY_CURRENT.public \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-staging.aarch64.repo b/utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-staging.aarch64.repo deleted file mode 100644 index d465e87f4f2..00000000000 --- a/utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-staging.aarch64.repo +++ /dev/null @@ -1,5 +0,0 @@ -[datadog-staging] -baseurl=https://yum.datad0g.com/beta/apm/aarch64/ -gpgcheck=1 -repo_gpgcheck=1 -gpgkey=https://s3.amazonaws.com/public-signing-keys/DATADOG_RPM_KEY_CURRENT.public \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-staging.x86_64.repo b/utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-staging.x86_64.repo deleted file mode 100644 index f2ed269ffce..00000000000 --- a/utils/build/virtual_machine/provisions/auto-inject/repositories/rpm/datadog-staging.x86_64.repo +++ /dev/null @@ -1,5 +0,0 @@ -[datadog-staging] -baseurl=https://yum.datad0g.com/beta/apm/x86_64/ -gpgcheck=1 -repo_gpgcheck=1 -gpgkey=https://s3.amazonaws.com/public-signing-keys/DATADOG_RPM_KEY_CURRENT.public \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/container-auto-inject-install-script/auto-inject_container_script.yml b/utils/build/virtual_machine/provisions/container-auto-inject-install-script/auto-inject_container_script.yml index 7d6b23df990..a68957dd6f2 100644 --- a/utils/build/virtual_machine/provisions/container-auto-inject-install-script/auto-inject_container_script.yml +++ b/utils/build/virtual_machine/provisions/container-auto-inject-install-script/auto-inject_container_script.yml @@ -10,6 +10,13 @@ - name: copy-agent-docker-compose local_path: utils/build/virtual_machine/provisions/auto-inject/docker/docker-compose-agent-prod.yml remote-command: | + #Env variables set on the scenario definition. Write to file and load + SCENARIO_AGENT_ENV="${DD_AGENT_ENV:-''}" + echo "${SCENARIO_AGENT_ENV}" > scenario_agent.env + echo "AGENT VARIABLES CONFIGURED FROM THE SCENARIO:" + cat scenario_agent.env + export $(cat scenario_agent.env | xargs) + sudo mkdir -p /var/run/datadog-installer sudo mkdir -p /opt/datadog/apm/inject/run sudo chmod 777 /opt/datadog/apm/inject/run diff --git a/utils/build/virtual_machine/provisions/container-auto-inject-install-script/provision.yml b/utils/build/virtual_machine/provisions/container-auto-inject-install-script/provision.yml index a7a85d5afbd..f55178d98bb 100644 --- a/utils/build/virtual_machine/provisions/container-auto-inject-install-script/provision.yml +++ b/utils/build/virtual_machine/provisions/container-auto-inject-install-script/provision.yml @@ -5,26 +5,32 @@ init-environment: !include utils/build/virtual_machine/provisions/auto-inject/au tested_components: install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-tested_components.yml -#Mandatory: Steps to install provision +#Mandatory: Steps to install provision provision_steps: - init-config #Very first machine actions, like disable auto updates - - prepare-repos #Configure the reporitories for install auto-injection - prepare-docker #Prepare the docker environment + - amazon-ecr-credential-helper # Install AWS ECR helper to download images from ECR + - patch-docker-daemon #Patch the docker daemon to avoid networking issues/ip conflicts incident-31160 - install-agent #Install the agent (allways latest release) - autoinjection_install_script #Install the auto-injection softaware 'datadog-apm-inject' and 'datadog-apm-library-$DD_LANG' init-config: cache: true + populate_env: false install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject_init_vm_config.yml -prepare-repos: - cache: true - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-prepare_repos.yml - prepare-docker: cache: true install: !include utils/build/virtual_machine/provisions/auto-inject/docker/auto-inject_prepare_docker.yml +amazon-ecr-credential-helper: + cache: true + install: !include utils/build/virtual_machine/provisions/auto-inject/docker/amazon-ecr-credential-helper.yml + +patch-docker-daemon: + cache: true + install: !include utils/build/virtual_machine/provisions/auto-inject/docker/patch-docker-daemon.yml + install-agent: install: - os_type: linux diff --git a/utils/build/virtual_machine/provisions/container-auto-inject/auto-inject_container_manual.yml b/utils/build/virtual_machine/provisions/container-auto-inject/auto-inject_container_manual.yml deleted file mode 100644 index 6bebed15510..00000000000 --- a/utils/build/virtual_machine/provisions/container-auto-inject/auto-inject_container_manual.yml +++ /dev/null @@ -1,86 +0,0 @@ -#Manual installation for lib-injection packages for container injection -- os_type: linux - os_distro: deb - copy_files: - - name: copy-binaries - local_path: binaries/ - - name: copy-docker-config - local_path: utils/build/virtual_machine/provisions/auto-inject/docker/docker_config.yaml - - name: copy-tracer-debug-config - local_path: utils/build/virtual_machine/provisions/auto-inject/tracer_debug/debug_config.yaml - remote-command: | - sudo mkdir -p /var/run/datadog-installer - sudo mkdir -p /opt/datadog/apm/inject/run - sudo chmod 777 /opt/datadog/apm/inject/run - printf "DD_APM_RECEIVER_SOCKET=/opt/datadog/apm/inject/run/apm.socket\nDD_DOGSTATSD_SOCKET=/opt/datadog/apm/inject/run/dsd.socket\nDD_USE_DOGSTATSD=true\n" | sudo tee /var/run/datadog-installer/environment - - #Sometimes we need to update the apt cache before installing the packages in order to get latest package version - sudo apt-get update -o Dir::Etc::sourcelist="sources.list.d/datadog-beta.list" -o Dir::Etc::sourceparts="-" -o APT::Get::List-Cleanup="0" || true - sudo apt-get update -o Dir::Etc::sourcelist="sources.list.d/datadog-stable.list" -o Dir::Etc::sourceparts="-" -o APT::Get::List-Cleanup="0" || true - architecture="" - case $(uname -m) in - x86_64) architecture="amd64" ;; - aarch64) architecture="arm64" ;; - esac - - if [ -e datadog-apm-inject_*_$architecture.deb ] - then - echo "Instaling datadog-apm-inject from local folder" - sudo apt install -y --reinstall ./datadog-apm-inject_*_$architecture.deb - else - echo "Instaling datadog-apm-inject from remote repository" - sudo apt-get install -y --reinstall -t $DD_deb_repo_name datadog-apm-inject - fi - - if [ -e datadog-apm-library-$DD_LANG_*_$architecture.deb ] - then - echo "Instaling datadog-apm-library-$DD_LANG from local folder" - sudo apt install -y --reinstall ./datadog-apm-library-$DD_LANG_*_$architecture.deb - else - echo "Instaling datadog-apm-library-$DD_LANG from remote repository" - sudo apt-get install -y --reinstall -t $DD_deb_repo_name datadog-apm-library-$DD_LANG - fi - - dd-container-install - sudo cp docker_config.yaml /etc/datadog-agent/inject/docker_config.yaml - sudo cp debug_config.yaml /etc/datadog-agent/inject/debug_config.yaml - -- os_type: linux - os_distro: rpm - copy_files: - - name: copy-binaries - local_path: binaries/ - - name: copy-docker-config - local_path: utils/build/virtual_machine/provisions/auto-inject/docker/docker_config.yaml - - name: copy-tracer-debug-config - local_path: utils/build/virtual_machine/provisions/auto-inject/tracer_debug/debug_config.yaml - remote-command: | - sudo mkdir -p /var/run/datadog-installer - sudo mkdir -p /opt/datadog/apm/inject/run - sudo chmod 777 /opt/datadog/apm/inject/run - printf "DD_APM_RECEIVER_SOCKET=/opt/datadog/apm/inject/run/apm.socket\nDD_DOGSTATSD_SOCKET=/opt/datadog/apm/inject/run/dsd.socket\nDD_USE_DOGSTATSD=true\n" | sudo tee /var/run/datadog-installer/environment - - architecture="" - case $(uname -m) in - x86_64) architecture="x86_64" ;; - aarch64) architecture="aarch64" ;; - esac - - if ls datadog-apm-inject-*.$architecture.rpm 1> /dev/null 2>&1; then - echo "Instaling datadog-apm-inject from local folder" - sudo yum -q list installed datadog-apm-inject &>/dev/null && sudo yum -y reinstall --disablerepo="*" datadog-apm-inject-*.$architecture.rpm || sudo yum -y install --disablerepo="*" datadog-apm-inject-*.$architecture.rpm - else - echo "Instaling datadog-apm-inject from remote repository" - sudo yum -q list installed datadog-apm-inject &>/dev/null && sudo yum -y reinstall --disablerepo="*" --enablerepo="$DD_rpm_repo_name" datadog-apm-inject || sudo yum -y install --disablerepo="*" --enablerepo="$DD_rpm_repo_name" datadog-apm-inject - fi - - if ls datadog-apm-library-$DD_LANG-*.$architecture.rpm 1> /dev/null 2>&1; then - echo "Instaling datadog-apm-library-$DD_LANG from local folder" - sudo yum -q list installed datadog-apm-library-$DD_LANG &>/dev/null && sudo yum -y reinstall --disablerepo="*" datadog-apm-library-$DD_LANG-*.$architecture.rpm || sudo yum -y install --disablerepo="*" datadog-apm-library-$DD_LANG-*.$architecture.rpm - else - echo "Instaling datadog-apm-library-$DD_LANG from remote repository" - sudo yum -q list installed datadog-apm-library-$DD_LANG &>/dev/null && sudo yum -y reinstall --disablerepo="*" --enablerepo="$DD_rpm_repo_name" datadog-apm-library-$DD_LANG || sudo yum -y install --disablerepo="*" --enablerepo="$DD_rpm_repo_name" datadog-apm-library-$DD_LANG - fi - dd-container-install - sudo cp docker_config.yaml /etc/datadog-agent/inject/docker_config.yaml - sudo cp debug_config.yaml /etc/datadog-agent/inject/debug_config.yaml diff --git a/utils/build/virtual_machine/provisions/container-auto-inject/provision.yml b/utils/build/virtual_machine/provisions/container-auto-inject/provision.yml deleted file mode 100644 index 559291c6d17..00000000000 --- a/utils/build/virtual_machine/provisions/container-auto-inject/provision.yml +++ /dev/null @@ -1,39 +0,0 @@ -#Optional: Load the environment variables -init-environment: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-environment.yml - -#Mandatory: Scripts to extract the installed/tested components (json {component1:version, component2:version}) -tested_components: - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-tested_components.yml - -#Mandatory: Steps to install provision -provision_steps: - - init-config #Very first machine actions, like disable auto updates - - prepare-repos #Configure the reporitories for install auto-injection - - prepare-docker #Prepare the docker environment - - install-agent #Install the agent (allways latest release) - - autoinjection_install_manual #Install the auto-injection softaware 'datadog-apm-inject' and 'datadog-apm-library-$DD_LANG' - -init-config: - cache: true - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject_init_vm_config.yml - -prepare-repos: - cache: true - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-prepare_repos.yml - -prepare-docker: - cache: true - install: !include utils/build/virtual_machine/provisions/auto-inject/docker/auto-inject_prepare_docker.yml - -install-agent: - install: - - os_type: linux - copy_files: - - name: copy-agent-docker-compose - local_path: utils/build/virtual_machine/provisions/auto-inject/docker/docker-compose-agent-prod.yml - remote-command: cat docker-compose-agent-prod.yml - -autoinjection_install_manual: - install: !include utils/build/virtual_machine/provisions/container-auto-inject/auto-inject_container_manual.yml - - diff --git a/utils/build/virtual_machine/provisions/host-auto-inject-install-script-profiling/auto-inject_host_script.yml b/utils/build/virtual_machine/provisions/host-auto-inject-install-script-profiling/auto-inject_host_script.yml deleted file mode 100644 index 64d32190965..00000000000 --- a/utils/build/virtual_machine/provisions/host-auto-inject-install-script-profiling/auto-inject_host_script.yml +++ /dev/null @@ -1,15 +0,0 @@ -#Execute script installation for lib-injection packages using install script -- os_type: linux - copy_files: - - name: copy-auto-install-script - local_path: utils/build/virtual_machine/provisions/auto-inject/repositories/autoinstall/execute_install_script.sh - - name: copy-tracer-debug-config - local_path: utils/build/virtual_machine/provisions/auto-inject/tracer_debug/debug_config.yaml - remote-command: | - printf "BOGUS=foo\n" | sudo tee -a /etc/environment - printf "DD_APM_RECEIVER_SOCKET=/opt/datadog/apm/inject/run/apm.socket\nDD_DOGSTATSD_SOCKET=/opt/datadog/apm/inject/run/dsd.socket\nDD_USE_DOGSTATSD=true\n" | sudo tee /var/run/datadog-installer/environment - DD_APM_INSTRUMENTATION_ENABLED=host DD_PROFILING_ENABLED=auto bash execute_install_script.sh - sudo mkdir -p /var/run/datadog-installer - sudo mkdir -p /opt/datadog/apm/inject/run - sudo chmod 777 /opt/datadog/apm/inject/run - sudo cp debug_config.yaml /etc/datadog-agent/inject/debug_config.yaml diff --git a/utils/build/virtual_machine/provisions/host-auto-inject-install-script-profiling/provision.yml b/utils/build/virtual_machine/provisions/host-auto-inject-install-script-profiling/provision.yml deleted file mode 100644 index aa1ebb7d0b2..00000000000 --- a/utils/build/virtual_machine/provisions/host-auto-inject-install-script-profiling/provision.yml +++ /dev/null @@ -1,32 +0,0 @@ -#Optional: Load the environment variables -init-environment: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-environment.yml - -#Mandatory: Scripts to extract the installed/tested components (json {component1:version, component2:version}) -tested_components: - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-tested_components.yml - -#Mandatory: Steps to install provision -provision_steps: - - init-config #Very first machine actions, like disable auto updates - - prepare-repos #Configure the reporitories for install auto-injection - - install-agent #Install the agent (allways latest release) - - autoinjection_install_script #Install the auto-injection softaware 'datadog-apm-inject' and 'datadog-apm-library-$DD_LANG' using the agent install script - -init-config: - cache: true - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject_init_vm_config.yml - -prepare-repos: - cache: true - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-prepare_repos.yml - -install-agent: - install: - - os_type: linux - remote-command: | - REPO_URL=$DD_agent_repo_url DD_AGENT_DIST_CHANNEL=$DD_agent_dist_channel DD_AGENT_MAJOR_VERSION=$DD_agent_major_version bash -c "$(curl -L https://s3.amazonaws.com/dd-agent/scripts/install_script_agent7.sh)" - -autoinjection_install_script: - install: !include utils/build/virtual_machine/provisions/host-auto-inject-install-script-profiling/auto-inject_host_script.yml - - diff --git a/utils/build/virtual_machine/provisions/host-auto-inject-install-script/auto-inject_host_script.yml b/utils/build/virtual_machine/provisions/host-auto-inject-install-script/auto-inject_host_script.yml index 84689d85961..fe2edf608ac 100644 --- a/utils/build/virtual_machine/provisions/host-auto-inject-install-script/auto-inject_host_script.yml +++ b/utils/build/virtual_machine/provisions/host-auto-inject-install-script/auto-inject_host_script.yml @@ -6,9 +6,12 @@ - name: copy-tracer-debug-config local_path: utils/build/virtual_machine/provisions/auto-inject/tracer_debug/debug_config.yaml remote-command: | - printf "DD_APM_RECEIVER_SOCKET=/opt/datadog/apm/inject/run/apm.socket\nDD_DOGSTATSD_SOCKET=/opt/datadog/apm/inject/run/dsd.socket\nDD_USE_DOGSTATSD=true\n" | sudo tee /var/run/datadog-installer/environment + # Env variables set on the scenario definition. Write to file and load + SCENARIO_AGENT_ENV="${DD_AGENT_ENV:-''}" + echo "${SCENARIO_AGENT_ENV}" > scenario_agent.env + echo "AGENT VARIABLES CONFIGURED FROM THE SCENARIO:" + cat scenario_agent.env + export $(cat scenario_agent.env | xargs) + DD_APM_INSTRUMENTATION_ENABLED=host bash execute_install_script.sh - sudo mkdir -p /var/run/datadog-installer - sudo mkdir -p /opt/datadog/apm/inject/run - sudo chmod 777 /opt/datadog/apm/inject/run sudo cp debug_config.yaml /etc/datadog-agent/inject/debug_config.yaml diff --git a/utils/build/virtual_machine/provisions/host-auto-inject-install-script/provision.yml b/utils/build/virtual_machine/provisions/host-auto-inject-install-script/provision.yml index 1693100d9dc..97c2a85a83e 100644 --- a/utils/build/virtual_machine/provisions/host-auto-inject-install-script/provision.yml +++ b/utils/build/virtual_machine/provisions/host-auto-inject-install-script/provision.yml @@ -5,28 +5,19 @@ init-environment: !include utils/build/virtual_machine/provisions/auto-inject/au tested_components: install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-tested_components.yml +#Optional: Extract the logs from the VM +vm_logs: + install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-vm_logs.yml + #Mandatory: Steps to install provision provision_steps: - init-config #Very first machine actions, like disable auto updates - - prepare-repos #Configure the reporitories for install auto-injection - - install-agent #Install the agent (allways latest release) - - autoinjection_install_script #Install the auto-injection softaware 'datadog-apm-inject' and 'datadog-apm-library-$DD_LANG' using the agent install script + - autoinjection_install_script #Install the injector, the agent, and the tracing library using the install script init-config: cache: true + populate_env: false install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject_init_vm_config.yml -prepare-repos: - cache: true - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-prepare_repos.yml - -install-agent: - install: - - os_type: linux - remote-command: | - REPO_URL=$DD_agent_repo_url DD_AGENT_DIST_CHANNEL=$DD_agent_dist_channel DD_AGENT_MAJOR_VERSION=$DD_agent_major_version bash -c "$(curl -L https://s3.amazonaws.com/dd-agent/scripts/install_script_agent7.sh)" - autoinjection_install_script: install: !include utils/build/virtual_machine/provisions/host-auto-inject-install-script/auto-inject_host_script.yml - - diff --git a/utils/build/virtual_machine/provisions/host-auto-inject-ld-preload/ld-preload.yml b/utils/build/virtual_machine/provisions/host-auto-inject-ld-preload/ld-preload.yml deleted file mode 100644 index 741713a4c06..00000000000 --- a/utils/build/virtual_machine/provisions/host-auto-inject-ld-preload/ld-preload.yml +++ /dev/null @@ -1,28 +0,0 @@ -#Manual installation for lib-injection packages -- os_type: linux - os_distro: deb - - copy_files: - - name: copy-helloworld-cpp - local_path: utils/build/virtual_machine/provisions/host-auto-inject-ld-preload/main.c - - remote-command: | - sudo apt install -y gcc - echo "Compiling main.c to main.so" - gcc -Wall -fPIC -shared -o main.so main.c -ldl - sudo mv main.so /usr/local/lib/ - sudo bash -c "echo /usr/local/lib/main.so >> /etc/ld.so.preload" - -- os_type: linux - os_distro: rpm - - copy_files: - - name: copy-helloworld-cpp - local_path: utils/build/virtual_machine/provisions/host-auto-inject-ld-preload/main.c - - remote-command: | - sudo yum groupinstall "Development Tools" - echo "Compiling main.c to main.so" - gcc -Wall -fPIC -shared -o main.so main.c -ldl - sudo mv main.so /usr/local/lib/ - sudo bash -c "echo /usr/local/lib/main.so >> /etc/ld.so.preload" \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/host-auto-inject-ld-preload/main.c b/utils/build/virtual_machine/provisions/host-auto-inject-ld-preload/main.c deleted file mode 100644 index 88e85fb6001..00000000000 --- a/utils/build/virtual_machine/provisions/host-auto-inject-ld-preload/main.c +++ /dev/null @@ -1,5 +0,0 @@ -void -_start() -{ - asm("mov $60,%rax; mov $0,%rdi; syscall"); -} \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/host-auto-inject-ld-preload/provision.yml b/utils/build/virtual_machine/provisions/host-auto-inject-ld-preload/provision.yml deleted file mode 100644 index da5338083f4..00000000000 --- a/utils/build/virtual_machine/provisions/host-auto-inject-ld-preload/provision.yml +++ /dev/null @@ -1,34 +0,0 @@ -#Optional: Load the environment variables -init-environment: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-environment.yml - -#Mandatory: Scripts to extract the installed/tested components (json {component1:version, component2:version}) -tested_components: - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-tested_components.yml - -#Mandatory: Steps to install provision -provision_steps: - - init-config #Very first machine actions, like disable auto updates - - prepare-repos #Configure the reporitories for install auto-injection - - install-agent #Install the agent (allways latest release) - - ld-so-preload #Add custom preload library to the system - - autoinjection_install_manual #Install the auto-injection softaware 'datadog-apm-inject' and 'datadog-apm-library-$DD_LANG' - -init-config: - cache: true - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject_init_vm_config.yml - -prepare-repos: - cache: true - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-prepare_repos.yml - -install-agent: - install: - - os_type: linux - remote-command: | - REPO_URL=$DD_agent_repo_url DD_AGENT_DIST_CHANNEL=$DD_agent_dist_channel DD_AGENT_MAJOR_VERSION=$DD_agent_major_version bash -c "$(curl -L https://s3.amazonaws.com/dd-agent/scripts/install_script_agent7.sh)" - -ld-so-preload: - install: !include utils/build/virtual_machine/provisions/host-auto-inject-ld-preload/ld-preload.yml - -autoinjection_install_manual: - install: !include utils/build/virtual_machine/provisions/host-auto-inject/auto-inject_host_manual.yml \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/host-auto-inject/auto-inject_host_manual.yml b/utils/build/virtual_machine/provisions/host-auto-inject/auto-inject_host_manual.yml deleted file mode 100644 index 7cd046818f4..00000000000 --- a/utils/build/virtual_machine/provisions/host-auto-inject/auto-inject_host_manual.yml +++ /dev/null @@ -1,94 +0,0 @@ -#Manual installation for lib-injection packages -- os_type: linux - os_distro: deb - - copy_files: - - name: copy-binaries - local_path: binaries/ - - - name: copy-tracer-debug-config - local_path: utils/build/virtual_machine/provisions/auto-inject/tracer_debug/debug_config.yaml - - - name: copy-microvm-patch - local_path: utils/build/virtual_machine/microvm/microvm_agent_restart_retry.sh - - - - remote-command: | - architecture="" - case $(uname -m) in - x86_64) architecture="amd64" ;; - aarch64) architecture="arm64" ;; - esac - - if [ -e datadog-apm-inject_*_$architecture.deb ] - then - echo "Instaling datadog-apm-inject from local folder" - sudo apt install -y --reinstall ./datadog-apm-inject_*_$architecture.deb - else - echo "Instaling datadog-apm-inject from remote repository" - sudo apt install -y --reinstall -t $DD_deb_repo_name datadog-apm-inject - fi - - if [ -e datadog-apm-library-$DD_LANG_*_$architecture.deb ] - then - echo "Instaling datadog-apm-library-$DD_LANG from local folder" - sudo apt install -y --reinstall ./datadog-apm-library-$DD_LANG_*_$architecture.deb - else - echo "Instaling datadog-apm-library-$DD_LANG from remote repository" - sudo apt install -y --reinstall -t $DD_deb_repo_name datadog-apm-library-$DD_LANG - fi - - dd-host-install - bash microvm_agent_restart_retry.sh - sudo cp debug_config.yaml /etc/datadog-agent/inject/debug_config.yaml - -- os_type: linux - os_distro: rpm - - copy_files: - - name: copy-binaries - local_path: binaries/ - - - name: copy-tracer-debug-config - local_path: utils/build/virtual_machine/provisions/auto-inject/tracer_debug/debug_config.yaml - - - name: copy-microvm-patch - local_path: utils/build/virtual_machine/microvm/microvm_agent_restart_retry.sh - - remote-command: | - architecture="" - case $(uname -m) in - x86_64) architecture="x86_64" ;; - aarch64) architecture="aarch64" ;; - esac - - if ls datadog-apm-inject-*.$architecture.rpm 1> /dev/null 2>&1; then - echo "Instaling datadog-apm-inject from local folder" - sudo yum -q list installed datadog-apm-inject &>/dev/null && sudo yum -y reinstall --disablerepo="*" datadog-apm-inject-*.$architecture.rpm || sudo yum -y install --disablerepo="*" datadog-apm-inject-*.$architecture.rpm - else - echo "Instaling datadog-apm-inject from remote repository" - sudo yum -q list installed datadog-apm-inject &>/dev/null && sudo yum -y reinstall --disablerepo="*" --enablerepo="$DD_rpm_repo_name" datadog-apm-inject || sudo yum -y install --disablerepo="*" --enablerepo="$DD_rpm_repo_name" datadog-apm-inject - fi - - if ls datadog-apm-library-$DD_LANG-*.$architecture.rpm 1> /dev/null 2>&1; then - echo "Instaling datadog-apm-library-$DD_LANG from local folder" - sudo yum -q list installed datadog-apm-library-$DD_LANG &>/dev/null && sudo yum -y reinstall --disablerepo="*" datadog-apm-library-$DD_LANG-*.$architecture.rpm || sudo yum -y install --disablerepo="*" datadog-apm-library-$DD_LANG-*.$architecture.rpm - else - echo "Instaling datadog-apm-library-$DD_LANG from remote repository" - sudo yum -q list installed datadog-apm-library-$DD_LANG &>/dev/null && sudo yum -y reinstall --disablerepo="*" --enablerepo="$DD_rpm_repo_name" datadog-apm-library-$DD_LANG || sudo yum -y install --disablerepo="*" --enablerepo="$DD_rpm_repo_name" datadog-apm-library-$DD_LANG - fi - dd-host-install - sh microvm_agent_restart_retry.sh - - sudo cp debug_config.yaml /etc/datadog-agent/inject/debug_config.yaml - - if ls datadog-apm-inject-*.$architecture.rpm 1> /dev/null 2>&1; then - echo "Skipping package signature verification for local package" - else - echo "Verify package signature. Fails if it isn't V4" - yumdownloader -y datadog-apm-inject - rpm -v --checksig *.rpm | grep -q "Header V4 RSA/SHA256 Signature" - echo "Package signature verified!" - rm datadog-apm-inject*.rpm || true - fi \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/host-auto-inject/provision.yml b/utils/build/virtual_machine/provisions/host-auto-inject/provision.yml deleted file mode 100644 index 3463f59991a..00000000000 --- a/utils/build/virtual_machine/provisions/host-auto-inject/provision.yml +++ /dev/null @@ -1,30 +0,0 @@ -#Optional: Load the environment variables -init-environment: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-environment.yml - -#Mandatory: Scripts to extract the installed/tested components (json {component1:version, component2:version}) -tested_components: - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-tested_components.yml - -#Mandatory: Steps to install provision -provision_steps: - - init-config #Very first machine actions, like disable auto updates - - prepare-repos #Configure the reporitories for install auto-injection - - install-agent #Install the agent (allways latest release) - - autoinjection_install_manual #Install the auto-injection softaware 'datadog-apm-inject' and 'datadog-apm-library-$DD_LANG' - -init-config: - cache: true - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject_init_vm_config.yml - -prepare-repos: - cache: true - install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-prepare_repos.yml - -install-agent: - install: - - os_type: linux - remote-command: | - REPO_URL=$DD_agent_repo_url DD_AGENT_DIST_CHANNEL=$DD_agent_dist_channel DD_AGENT_MAJOR_VERSION=$DD_agent_major_version bash -c "$(curl -L https://s3.amazonaws.com/dd-agent/scripts/install_script_agent7.sh)" - -autoinjection_install_manual: - install: !include utils/build/virtual_machine/provisions/host-auto-inject/auto-inject_host_manual.yml \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/installer-auto-inject/auto-inject_installer_script.yml b/utils/build/virtual_machine/provisions/installer-auto-inject/auto-inject_installer_script.yml deleted file mode 100644 index 1d357359d10..00000000000 --- a/utils/build/virtual_machine/provisions/installer-auto-inject/auto-inject_installer_script.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Installs the installer package -- os_type: linux - copy_files: - - name: copy-tracer-debug-config - local_path: utils/build/virtual_machine/provisions/auto-inject/tracer_debug/debug_config.yaml - - name: copy-docker-config - local_path: utils/build/virtual_machine/provisions/auto-inject/docker/docker_config.yaml - - remote-command: | - sudo -E sh -c "sudo mkdir -p /etc/datadog-agent && echo \"api_key: ${DD_API_KEY}\" > /etc/datadog-agent/datadog.yaml" - DD_INSTALLER_REGISTRY_URL="localhost:12345/datadog" DD_REPO_URL=datad0g.com DD_INSTALLER=true DD_NO_AGENT_INSTALL=true bash -c "$(curl -L https://s3.amazonaws.com/dd-agent/scripts/install_script_agent7.sh)" - - sudo mkdir -p /etc/datadog-agent/inject - sudo cp docker_config.yaml /etc/datadog-agent/inject/docker_config.yaml - sudo cp debug_config.yaml /etc/datadog-agent/inject/debug_config.yaml diff --git a/utils/build/virtual_machine/provisions/installer-auto-inject/provision.yml b/utils/build/virtual_machine/provisions/installer-auto-inject/provision.yml index 2260f67c893..65366cb4c82 100644 --- a/utils/build/virtual_machine/provisions/installer-auto-inject/provision.yml +++ b/utils/build/virtual_machine/provisions/installer-auto-inject/provision.yml @@ -5,104 +5,39 @@ init-environment: !include utils/build/virtual_machine/provisions/auto-inject/au tested_components: install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-tested_components.yml +#Optional: Extract the logs from the VM +vm_logs: + install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-vm_logs.yml + # Mandatory: Steps to provision VM provision_steps: - init-config # Init the VM configuration - prepare-docker # Install docker - - setup-testing-dependencies # Pull the right docker images & install crane - - setup-local-registry # Setup a local registry with injector & tracer OCIs + - amazon-ecr-credential-helper # Install AWS ECR helper to download images from ECR + - patch-docker-daemon #Patch the docker daemon to avoid networking issues/ip conflicts incident-31160 + - pre-install-installer # we install only the installer and we cached it. The goal is to force download the required deps for the installer and cache them - install-installer # Install the installer - - installer-bootstrap # Bootstrap the agent, library, and injector init-config: cache: true + populate_env: false install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject_init_vm_config.yml prepare-docker: cache: true install: !include utils/build/virtual_machine/provisions/auto-inject/docker/auto-inject_prepare_docker.yml -setup-testing-dependencies: +amazon-ecr-credential-helper: cache: true - install: - - os_type: linux - os_distro: deb - remote-command: | - sudo rm -rf /usr/local/go - sudo curl https://dl.google.com/go/go1.22.1.linux-$(dpkg --print-architecture).tar.gz --output go.tar.gz - sudo tar -C /usr/local -xzf go.tar.gz - export PATH=$PATH:/usr/local/go/bin - export PATH=$PATH:$(go env GOPATH)/bin - go install github.com/google/go-containerregistry/cmd/crane@latest - go install github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cli/docker-credential-ecr-login@latest - sudo mkdir -p ~/.docker - echo '{"credHelpers":{"669783387624.dkr.ecr.us-east-1.amazonaws.com": "ecr-login"}}' | sudo tee ~/.docker/config.json - sudo mkdir -p /root/.docker - echo '{"credHelpers":{"669783387624.dkr.ecr.us-east-1.amazonaws.com": "ecr-login"}}' | sudo tee /root/.docker/config.json - sudo PATH="$PATH:$(/usr/local/go/bin/go env GOPATH)/bin" docker pull 669783387624.dkr.ecr.us-east-1.amazonaws.com/dockerhub/library/registry:2 - - os_type: linux - os_distro: rpm - remote-command: | - sudo rm -rf /usr/local/go - sudo curl https://dl.google.com/go/go1.22.1.linux-$(rpm --eval '%{_arch}' | sed s/aarch64/arm64/ | sed s/x86_64/amd64/).tar.gz --output go.tar.gz - sudo tar -C /usr/local -xzf go.tar.gz - export PATH=$PATH:/usr/local/go/bin - export PATH=$PATH:$(go env GOPATH)/bin - go install github.com/google/go-containerregistry/cmd/crane@latest - go install github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cli/docker-credential-ecr-login@latest - sudo mkdir -p ~/.docker - echo '{"credHelpers":{"669783387624.dkr.ecr.us-east-1.amazonaws.com": "ecr-login"}}' | sudo tee ~/.docker/config.json - sudo mkdir -p /root/.docker - echo '{"credHelpers":{"669783387624.dkr.ecr.us-east-1.amazonaws.com": "ecr-login"}}' | sudo tee /root/.docker/config.json - sudo PATH="$PATH:$(/usr/local/go/bin/go env GOPATH)/bin" docker pull 669783387624.dkr.ecr.us-east-1.amazonaws.com/dockerhub/library/registry:2 - -setup-local-registry: - install: - - os_type: linux - # By default we use the latest staging images - # Port 12345 is used to avoid conflict with the agent later on - remote-command: | - export PATH=$PATH:/usr/local/go/bin - export PATH=$PATH:$(go env GOPATH)/bin - sudo systemctl start docker - sudo docker run -d -p 12345:5000 --restart=always --name registry 669783387624.dkr.ecr.us-east-1.amazonaws.com/dockerhub/library/registry:2 - sleep 10 - - if [ -n "${DD_INSTALLER_LIBRARY_VERSION}" ]; then - export LIBRARY_OCI_URL="669783387624.dkr.ecr.us-east-1.amazonaws.com/apm-library-${DD_LANG}-package:${DD_INSTALLER_LIBRARY_VERSION}" - else - export LIBRARY_OCI_URL="669783387624.dkr.ecr.us-east-1.amazonaws.com/dockerhub/datadog/apm-library-${DD_LANG}-package-dev:latest" - fi - crane copy "${LIBRARY_OCI_URL}" localhost:12345/datadog/apm-library-${DD_LANG}-package:latest - - if [ -n "${DD_INSTALLER_INJECTOR_VERSION}" ]; then - export INJECTOR_OCI_URL="669783387624.dkr.ecr.us-east-1.amazonaws.com/apm-inject-package:${DD_INSTALLER_INJECTOR_VERSION}" - else - export INJECTOR_OCI_URL="669783387624.dkr.ecr.us-east-1.amazonaws.com/dockerhub/datadog/apm-inject-package-dev:0.13.2-beta1-dev.b0d6e40.glci531210996.g95332787-1" - fi - crane copy "${INJECTOR_OCI_URL}" localhost:12345/datadog/apm-inject-package:latest + install: !include utils/build/virtual_machine/provisions/auto-inject/docker/amazon-ecr-credential-helper.yml - if [ -n "${DD_INSTALLER_AGENT_VERSION}" ]; then - export AGENT_OCI_URL="669783387624.dkr.ecr.us-east-1.amazonaws.com/agent-package:${DD_INSTALLER_AGENT_VERSION}" - else - export AGENT_OCI_URL="669783387624.dkr.ecr.us-east-1.amazonaws.com/dockerhub/datadog/agent-package-dev:latest" - fi - crane copy "${AGENT_OCI_URL}" localhost:12345/datadog/agent-package:latest - - if [ -n "${DD_INSTALLER_INSTALLER_VERSION}" ]; then - export INSTALLER_OCI_URL="669783387624.dkr.ecr.us-east-1.amazonaws.com/installer-package:${DD_INSTALLER_INSTALLER_VERSION}" - else - export INSTALLER_OCI_URL="669783387624.dkr.ecr.us-east-1.amazonaws.com/dockerhub/datadog/installer-package-dev:latest" - fi - crane copy "${INSTALLER_OCI_URL}" localhost:12345/datadog/installer-package:latest +patch-docker-daemon: + cache: true + install: !include utils/build/virtual_machine/provisions/auto-inject/docker/patch-docker-daemon.yml + +pre-install-installer: + cache: true + install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject_pre_installer_manual.yml install-installer: - install: !include utils/build/virtual_machine/provisions/installer-auto-inject/auto-inject_installer_script.yml - -installer-bootstrap: - install: - - os_type: linux - remote-command: | - sudo datadog-installer install "oci://localhost:12345/datadog/apm-inject-package:latest" - sudo datadog-installer install "oci://localhost:12345/datadog/agent-package:latest" - sudo datadog-installer install "oci://localhost:12345/datadog/apm-library-${DD_LANG}-package:latest" + install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject_installer_manual.yml diff --git a/utils/build/virtual_machine/provisions/local-auto-inject-install-script/auto-inject_apm_libraries_from_binaries.yml b/utils/build/virtual_machine/provisions/local-auto-inject-install-script/auto-inject_apm_libraries_from_binaries.yml new file mode 100644 index 00000000000..e24addc7b5b --- /dev/null +++ b/utils/build/virtual_machine/provisions/local-auto-inject-install-script/auto-inject_apm_libraries_from_binaries.yml @@ -0,0 +1,12 @@ +#Execute script installation for lib-injection packages using install script +- os_type: linux + copy_files: + - name: copy-binaries + local_path: binaries + - name: copy-start-agent-script + local_path: utils/build/virtual_machine/microvm/microvm_agent_restart_retry.sh + remote-command: | + mkdir /shared_volume/datadog-apm-library + find /shared_volume -name "datadog-apm-library*.tar" -exec sh -c 'tar xvf {} -C /shared_volume/datadog-apm-library' \; + sudo datadog-installer install file:///shared_volume/datadog-apm-library + bash /shared_volume/microvm_agent_restart_retry.sh \ No newline at end of file diff --git a/utils/build/virtual_machine/provisions/local-auto-inject-install-script/provision.yml b/utils/build/virtual_machine/provisions/local-auto-inject-install-script/provision.yml new file mode 100644 index 00000000000..ceac6b6f14d --- /dev/null +++ b/utils/build/virtual_machine/provisions/local-auto-inject-install-script/provision.yml @@ -0,0 +1,34 @@ +#Optional: Load the environment variables +init-environment: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-environment.yml + +#Mandatory: Scripts to extract the installed/tested components (json {component1:version, component2:version}) +tested_components: + install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-tested_components.yml + +#Optional: Extract the logs from the VM +vm_logs: + install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject-vm_logs.yml + +#Mandatory: Steps to install provision +provision_steps: + - init-config #Very first machine actions, like disable auto updates + - install-agent #Install the agent (allways latest release) + - autoinjection_install_script #Install the auto-injection softaware 'datadog-apm-inject' and 'datadog-apm-library-$DD_LANG' using the agent install script + - install-local-apm-library + +init-config: + cache: true + populate_env: false + install: !include utils/build/virtual_machine/provisions/auto-inject/auto-inject_init_vm_config.yml + +install-agent: + install: + - os_type: linux + remote-command: | + REPO_URL=$DD_agent_repo_url DD_AGENT_DIST_CHANNEL=$DD_agent_dist_channel DD_AGENT_MAJOR_VERSION=$DD_agent_major_version bash -c "$(curl -L https://install.datadoghq.com/scripts/install_script_agent7.sh)" + +autoinjection_install_script: + install: !include utils/build/virtual_machine/provisions/host-auto-inject-install-script/auto-inject_host_script.yml + +install-local-apm-library: + install: !include utils/build/virtual_machine/provisions/local-auto-inject-install-script/auto-inject_apm_libraries_from_binaries.yml \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/common/create_and_run_app_container.sh b/utils/build/virtual_machine/weblogs/common/create_and_run_app_container.sh new file mode 100755 index 00000000000..3747f4898ea --- /dev/null +++ b/utils/build/virtual_machine/weblogs/common/create_and_run_app_container.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# shellcheck disable=SC2015 + +set -e + +# shellcheck disable=SC2035 +sudo chmod -R 755 * + +rm -rf Dockerfile || true +cp Dockerfile.template Dockerfile || true + +sudo systemctl start docker # Start docker service if it's not started + +#workaround. Remove the system-tests cloned folder. The sources are copied to current home folder +#if we don't remove it, the dotnet restore will try to restore the system-tests folder +sudo rm -rf system-tests || true + +#The parameter RUNTIME is used only for dotnet +sudo docker build --no-cache --build-arg RUNTIME="bullseye-slim" -t system-tests/local . + +if [ -f docker-compose-agent-prod.yml ]; then + # Agent may be installed in a different way + sudo -E docker-compose -f docker-compose-agent-prod.yml up -d --remove-orphans datadog --wait --wait-timeout 120 +fi +#Env variables set on the scenario definition. Write to file and load +if [ ! -f scenario_app.env ] +then + SCENARIO_APP_ENV="${DD_APP_ENV:-''}" + echo "$SCENARIO_APP_ENV" | tr '[:space:]' '\n' > scenario_app.env + echo "APP VARIABLES CONFIGURED FROM THE SCENARIO:" + cat scenario_app.env +fi +sudo -E docker-compose -f docker-compose.yml up -d test-app + +echo "..:: RUNNING DOCKER SERVICES ::.." +sudo docker-compose ps +if [ -f docker-compose-agent-prod.yml ]; then + echo "..:: DATADOG AGENT OUTPUT ::.." + sudo docker-compose -f docker-compose-agent-prod.yml logs datadog +fi +echo "..:: WEBLOG APP OUTPUT ::.." +sudo docker-compose logs +echo "RUN DONE" diff --git a/utils/build/virtual_machine/weblogs/common/create_and_run_app_multicontainer.sh b/utils/build/virtual_machine/weblogs/common/create_and_run_app_multicontainer.sh new file mode 100755 index 00000000000..6d989b66d5f --- /dev/null +++ b/utils/build/virtual_machine/weblogs/common/create_and_run_app_multicontainer.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# shellcheck disable=SC2015 + +set -e + +# shellcheck disable=SC2035 +sudo chmod -R 755 * + +sudo systemctl start docker # Start docker service if it's not started + +#workaround. Remove the system-tests cloned folder. The sources are copied to current home folder +#if we don't remove it, the dotnet restore will try to restore the system-tests folder +sudo rm -rf system-tests || true + +#Build apps +sudo docker-compose -f docker-compose.yml build --parallel + +if [ -f docker-compose-agent-prod.yml ]; then + # Agent may be installed in a different way + sudo -E docker-compose -f docker-compose-agent-prod.yml up -d --remove-orphans datadog --wait --wait-timeout 120 +fi + +#Env variables set on the scenario definition. Write to file and load +if [ ! -f scenario_app.env ] +then + SCENARIO_APP_ENV="${DD_APP_ENV:-''}" + echo "$SCENARIO_APP_ENV" | tr '[:space:]' '\n' > scenario_app.env + echo "APP VARIABLES CONFIGURED FROM THE SCENARIO:" + cat scenario_app.env +fi +sudo -E docker-compose -f docker-compose.yml up -d --wait --wait-timeout 180 || true + +echo "..:: RUNNING DOCKER SERVICES ::.." +sudo docker-compose -f docker-compose.yml ps + +echo "..:: WEBLOG APP OUTPUT ::.." +sudo docker-compose -f docker-compose.yml logs +echo "RUN DONE" diff --git a/utils/build/virtual_machine/weblogs/common/create_and_run_app_service.sh b/utils/build/virtual_machine/weblogs/common/create_and_run_app_service.sh new file mode 100755 index 00000000000..afdb3bbe658 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/common/create_and_run_app_service.sh @@ -0,0 +1,33 @@ +#!/bin/bash +echo "START RUN APP" + +#Create folder for app logs +sudo mkdir /var/log/datadog_weblog +sudo chmod 777 /var/log/datadog_weblog + +COMMAND_LINE=$1 +APP_ENV="${2:-''}" + +#ENV variables set on the scenario definition +SCENARIO_APP_ENV="${DD_APP_ENV:-''}" + +echo "$APP_ENV" | tr '[:space:]' '\n' > /var/log/datadog_weblog/app.env +sudo chmod 777 /var/log/datadog_weblog/app.env + +echo "$SCENARIO_APP_ENV" | tr '[:space:]' '\n' > /var/log/datadog_weblog/scenario_app.env +sudo chmod 777 /var/log/datadog_weblog/scenario_app.env + +echo "Using app environment variables:" +cat /var/log/datadog_weblog/app.env + +echo "Using scenario app environment variables:" +cat /var/log/datadog_weblog/scenario_app.env + +sed -i "s,APP_RUN_COMMAND,$COMMAND_LINE,g" test-app.service +sudo cp test-app.service /etc/systemd/system/test-app.service +sudo systemctl daemon-reload +sudo systemctl enable test-app.service +sudo systemctl start test-app.service +sudo systemctl status test-app.service + +echo "RUN DONE" \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/common/docker-compose.yml b/utils/build/virtual_machine/weblogs/common/docker-compose.yml new file mode 100644 index 00000000000..8385144411e --- /dev/null +++ b/utils/build/virtual_machine/weblogs/common/docker-compose.yml @@ -0,0 +1,8 @@ +version: '3' +services: + test-app: + env_file: "scenario_app.env" + container_name: test-app + image: system-tests/local:latest + ports: + - 5985:18080 diff --git a/utils/build/virtual_machine/weblogs/common/test-app.service b/utils/build/virtual_machine/weblogs/common/test-app.service new file mode 100644 index 00000000000..2e17d8a806d --- /dev/null +++ b/utils/build/virtual_machine/weblogs/common/test-app.service @@ -0,0 +1,25 @@ +[Unit] +Description=Weblog App Service +After=syslog.target network.target + +[Service] +SuccessExitStatus=143 + +User=datadog + +Type=simple + +Environment=DD_CONFIG_SOURCES=LOCAL:/etc/datadog-agent/inject/debug_config.yaml +Environment=DD_APM_INSTRUMENTATION_DEBUG=TRUE +Environment=DD_TRACE_DEBUG=true + +EnvironmentFile=/var/log/datadog_weblog/app.env +EnvironmentFile=/var/log/datadog_weblog/scenario_app.env +EnvironmentFile=/etc/environment + +WorkingDirectory=/home/datadog +ExecStart=/bin/bash -c 'APP_RUN_COMMAND >> /var/log/datadog_weblog/app.log 2>&1 > /etc/environment' - sudo sh -c 'echo "DD_APM_INSTRUMENTATION_OUTPUT_PATHS=/opt/datadog/logs_injection/host_injection.log" >> /etc/environment' - source /etc/environment diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-container/docker-compose.yml b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-container/docker-compose.yml deleted file mode 100644 index cb2f3d3b681..00000000000 --- a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-container/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: '3' -services: - test-app-dotnet: - container_name: test-app-dotnet - image: system-tests/local:latest - ports: - - 5985:18080 diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-container/test-app-dotnet_docker_compose_run.sh b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-container/test-app-dotnet_docker_compose_run.sh deleted file mode 100755 index fdcf8f4ada9..00000000000 --- a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-container/test-app-dotnet_docker_compose_run.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC2015 - -set -e - -# shellcheck disable=SC2035 -sudo chmod -R 755 * - -sudo docker build --build-arg RUNTIME="bullseye-slim" -t system-tests/local . -if [ -f docker-compose-agent-prod.yml ]; then - # Agent may be installed in a different way - sudo -E docker-compose -f docker-compose-agent-prod.yml up -d --remove-orphans datadog - sleep 30 -fi -sudo -E docker-compose -f docker-compose.yml up -d test-app-dotnet - -echo "**************** RUNNING DOCKER SERVICES *****************" -sudo docker-compose ps -if [ -f docker-compose-agent-prod.yml ]; then - echo "**************** DATADOG AGENT OUTPUT ********************" - sudo docker-compose -f docker-compose-agent-prod.yml logs datadog -fi -echo "**************** WEBLOG APP OUTPUT********************" -sudo docker-compose logs - -echo "RUN DONE" diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/Dockerfile.dotnet_6-alpine b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/Dockerfile.dotnet_6-alpine new file mode 100644 index 00000000000..bb4eaedd903 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/Dockerfile.dotnet_6-alpine @@ -0,0 +1,28 @@ +ARG RUNTIME="bullseye-slim" + +# We only ship the published app in the image +# so we only use ASPNET runtime as the base-image +FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build +WORKDIR /app +COPY MinimalWebApp.csproj . +RUN sed -i "s/net7.0/net6.0/g" MinimalWebApp.csproj +RUN cat MinimalWebApp.csproj +RUN dotnet restore +COPY . . +RUN sed -i "s/net7.0/net6.0/g" MinimalWebApp.csproj +RUN cat MinimalWebApp.csproj +RUN dotnet build -c Release + +FROM build AS publish +RUN dotnet publish -c Release -o /publish + +FROM base AS final +WORKDIR /app +EXPOSE 18080 +ENV ASPNETCORE_URLS=http://+:18080 +COPY --from=publish /publish . + +ENTRYPOINT ["dotnet", "MinimalWebApp.dll"] diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/Dockerfile.dotnet_8-alpine b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/Dockerfile.dotnet_8-alpine new file mode 100644 index 00000000000..5aa00b5da05 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/Dockerfile.dotnet_8-alpine @@ -0,0 +1,28 @@ +ARG RUNTIME="bullseye-slim" + +# We only ship the published app in the image +# so we only use ASPNET runtime as the base-image +FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build +WORKDIR /app +COPY MinimalWebApp.csproj . +RUN sed -i "s/net7.0/net8.0/g" MinimalWebApp.csproj +RUN cat MinimalWebApp.csproj +RUN dotnet restore +COPY . . +RUN sed -i "s/net7.0/net8.0/g" MinimalWebApp.csproj +RUN cat MinimalWebApp.csproj +RUN dotnet build -c Release + +FROM build AS publish +RUN dotnet publish -c Release -o /publish + +FROM base AS final +WORKDIR /app +EXPOSE 18080 +ENV ASPNETCORE_URLS=http://+:18080 +COPY --from=publish /publish . + +ENTRYPOINT ["dotnet", "MinimalWebApp.dll"] diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/Dockerfile.reverseproxy b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/Dockerfile.reverseproxy new file mode 100644 index 00000000000..82cdb622233 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/Dockerfile.reverseproxy @@ -0,0 +1,3 @@ +FROM public.ecr.aws/nginx/nginx:stable-perl + +COPY nginx.conf /etc/nginx/nginx.conf \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/docker-compose.yml b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/docker-compose.yml new file mode 100644 index 00000000000..e21125c9964 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/docker-compose.yml @@ -0,0 +1,33 @@ +version: '2' + +services: + reverseproxy: + image: reverseproxy:latest + ports: + - 5985:8080 + restart: always + build: + context: . + dockerfile: Dockerfile.reverseproxy + healthcheck: + test: "curl -f http://localhost:8080" + + dotnet_8: + env_file: "scenario_app.env" + image: system-tests/dotnet_8:latest + restart: always + build: + context: . + dockerfile: Dockerfile.dotnet_8-alpine + healthcheck: + test: "curl -f http://localhost:18080" + + dotnet_6: + env_file: "scenario_app.env" + image: system-tests/dotnet_6:latest + restart: always + build: + context: . + dockerfile: Dockerfile.dotnet_6-alpine + healthcheck: + test: "curl -f http://localhost:18080" diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/nginx.conf b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/nginx.conf new file mode 100644 index 00000000000..66589f2b89f --- /dev/null +++ b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multialpine/nginx.conf @@ -0,0 +1,49 @@ +worker_processes 1; + +events { worker_connections 1024; } + + +http { + + log_format compression '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $upstream_addr ' + '"$http_referer" "$http_user_agent" "$gzip_ratio"'; + + upstream dotnet_8_app { + server dotnet_8:18080; + } + upstream dotnet_6_app { + server dotnet_6:18080; + } + server { + listen 8080; + access_log /var/log/nginx/access.log compression; + + location / { + default_type application/json; + return 200 "{ + 'app_type':'multicontainer', + 'apps':[{ + 'runtime':'8.0', + 'type':'alpine', + 'url':'/dotnet_8/' + },{ + 'runtime':'6.0', + 'type':'alpine', + 'url':'/dotnet_6/' + } + + ] + }"; + } + + location /dotnet_8/ { + proxy_pass http://dotnet_8_app/; + proxy_redirect off; + } + location /dotnet_6/ { + proxy_pass http://dotnet_6_app/; + proxy_redirect off; + } + } +} diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/Dockerfile.dotnet_6 b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/Dockerfile.dotnet_6 new file mode 100644 index 00000000000..a06d453b49c --- /dev/null +++ b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/Dockerfile.dotnet_6 @@ -0,0 +1,28 @@ +ARG RUNTIME="bullseye-slim" + +# We only ship the published app in the image +# so we only use ASPNET runtime as the base-image +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +WORKDIR /app +COPY MinimalWebApp.csproj . +RUN sed -i "s/net7.0/net6.0/g" MinimalWebApp.csproj +RUN cat MinimalWebApp.csproj +RUN dotnet restore +COPY . . +RUN sed -i "s/net7.0/net6.0/g" MinimalWebApp.csproj +RUN cat MinimalWebApp.csproj +RUN dotnet build -c Release + +FROM build AS publish +RUN dotnet publish -c Release -o /publish + +FROM base AS final +WORKDIR /app +EXPOSE 18080 +ENV ASPNETCORE_URLS=http://+:18080 +COPY --from=publish /publish . + +ENTRYPOINT ["dotnet", "MinimalWebApp.dll"] diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/Dockerfile.dotnet_8 b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/Dockerfile.dotnet_8 new file mode 100644 index 00000000000..455e3d47736 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/Dockerfile.dotnet_8 @@ -0,0 +1,28 @@ +ARG RUNTIME="bullseye-slim" + +# We only ship the published app in the image +# so we only use ASPNET runtime as the base-image +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +WORKDIR /app +COPY MinimalWebApp.csproj . +RUN sed -i "s/net7.0/net8.0/g" MinimalWebApp.csproj +RUN cat MinimalWebApp.csproj +RUN dotnet restore +COPY . . +RUN sed -i "s/net7.0/net8.0/g" MinimalWebApp.csproj +RUN cat MinimalWebApp.csproj +RUN dotnet build -c Release + +FROM build AS publish +RUN dotnet publish -c Release -o /publish + +FROM base AS final +WORKDIR /app +EXPOSE 18080 +ENV ASPNETCORE_URLS=http://+:18080 +COPY --from=publish /publish . + +ENTRYPOINT ["dotnet", "MinimalWebApp.dll"] diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/Dockerfile.reverseproxy b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/Dockerfile.reverseproxy new file mode 100644 index 00000000000..82cdb622233 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/Dockerfile.reverseproxy @@ -0,0 +1,3 @@ +FROM public.ecr.aws/nginx/nginx:stable-perl + +COPY nginx.conf /etc/nginx/nginx.conf \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/docker-compose.yml b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/docker-compose.yml new file mode 100644 index 00000000000..99e4b7f106a --- /dev/null +++ b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/docker-compose.yml @@ -0,0 +1,33 @@ +version: '2' + +services: + reverseproxy: + image: reverseproxy:latest + ports: + - 5985:8080 + restart: always + build: + context: . + dockerfile: Dockerfile.reverseproxy + healthcheck: + test: "curl -f http://localhost:8080" + + dotnet_8: + env_file: "scenario_app.env" + image: system-tests/dotnet_8:latest + restart: always + build: + context: . + dockerfile: Dockerfile.dotnet_8 + healthcheck: + test: "true" + + dotnet_6: + env_file: "scenario_app.env" + image: system-tests/dotnet_6:latest + restart: always + build: + context: . + dockerfile: Dockerfile.dotnet_6 + healthcheck: + test: "true" diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/nginx.conf b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/nginx.conf new file mode 100644 index 00000000000..9723bae3931 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-multicontainer/nginx.conf @@ -0,0 +1,49 @@ +worker_processes 1; + +events { worker_connections 1024; } + + +http { + + log_format compression '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $upstream_addr ' + '"$http_referer" "$http_user_agent" "$gzip_ratio"'; + + upstream dotnet_8_app { + server dotnet_8:18080; + } + upstream dotnet_6_app { + server dotnet_6:18080; + } + server { + listen 8080; + access_log /var/log/nginx/access.log compression; + + location / { + default_type application/json; + return 200 "{ + 'app_type':'multicontainer', + 'apps':[{ + 'runtime':'8.0', + 'type':'container', + 'url':'/dotnet_8/' + },{ + 'runtime':'6.0', + 'type':'container', + 'url':'/dotnet_6/' + } + + ] + }"; + } + + location /dotnet_8/ { + proxy_pass http://dotnet_8_app/; + proxy_redirect off; + } + location /dotnet_6/ { + proxy_pass http://dotnet_6_app/; + proxy_redirect off; + } + } +} diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-unsupported/test-app-dotnet-unsupported_run.sh b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-unsupported/test-app-dotnet-unsupported_run.sh new file mode 100644 index 00000000000..69cadc0b104 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet-unsupported/test-app-dotnet-unsupported_run.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -e + +# shellcheck disable=SC2035 +sudo chmod -R 755 * + +echo "START dotnet APP (debug active)" +#If we are trying to inject the library on the "restore" or "build" command we should show the traces +export DD_APM_INSTRUMENTATION_DEBUG=false +export DOTNET_DbgEnableMiniDump=1 +export DOTNET_DbgMiniDumpType=4 +export DOTNET_CreateDumpDiagnostics=1 +export DOTNET_DbgMiniDumpName=/var/log/datadog/dotnet/coredump.txt +export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 + +#workaround. Remove the system-tests cloned folder. The sources are copied to current home folder +#if we don't remove it, the dotnet restore will try to restore the system-tests folder +sudo rm -rf system-tests + +#Restore, build and publish the app +sudo dotnet publish -c Release -o /home/datadog + +#Copy app service and start it +export DD_APM_INSTRUMENTATION_DEBUG=true +sudo chmod 755 create_and_run_app_service.sh +./create_and_run_app_service.sh "dotnet MinimalWebApp.dll" "ASPNETCORE_URLS=http://+:5985 DOTNET_DbgEnableMiniDump=1 DOTNET_DbgMiniDumpType=4" + +echo "RUN dotnet DONE" \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet/test-app-dotnet_run.sh b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet/test-app-dotnet_run.sh index a9541aaf966..94d43e0b136 100755 --- a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet/test-app-dotnet_run.sh +++ b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet/test-app-dotnet_run.sh @@ -4,7 +4,7 @@ set -e # shellcheck disable=SC2035 sudo chmod -R 755 * -echo "START RUN APP (debug active)" +echo "START dotnet APP (debug active)" #If we are trying to inject the library on the "restore" or "build" command we should show the traces export DD_APM_INSTRUMENTATION_DEBUG=false export DOTNET_DbgEnableMiniDump=1 @@ -15,21 +15,18 @@ export DOTNET_DbgMiniDumpName=/var/log/datadog/dotnet/coredump.txt #We are running the app for dotnet 6.0 sudo sed -i "s/net7.0/net6.0/g" MinimalWebApp.csproj +#workaround. Remove the system-tests cloned folder. The sources are copied to current home folder +#if we don't remove it, the dotnet restore will try to restore the system-tests folder +sudo rm -rf system-tests + #Restore, build and publish the app dotnet restore dotnet build -c Release -sudo dotnet publish -c Release -o /home/datadog/publish +sudo dotnet publish -c Release -o /home/datadog #Copy app service and start it export DD_APM_INSTRUMENTATION_DEBUG=true -sudo cp test-app.service /etc/systemd/system/test-app.service -sudo systemctl daemon-reload -sudo systemctl enable test-app.service -sudo systemctl start test-app.service -sudo systemctl status test-app.service - -#Wait for the app to start and show the logs -sleep 5 -sudo cat /home/datadog/app-std.out +sudo chmod 755 create_and_run_app_service.sh +./create_and_run_app_service.sh "dotnet MinimalWebApp.dll" "ASPNETCORE_URLS=http://+:5985 DOTNET_DbgEnableMiniDump=1 DOTNET_DbgMiniDumpType=4" -echo "RUN DONE" +echo "RUN dotnet DONE" \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet/test-app.service b/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet/test-app.service deleted file mode 100644 index 3ae70ac21ab..00000000000 --- a/utils/build/virtual_machine/weblogs/dotnet/test-app-dotnet/test-app.service +++ /dev/null @@ -1,21 +0,0 @@ -[Unit] -Description=DotNet Weblog App Service -After=syslog.target network.target - -[Service] -SuccessExitStatus=143 - -User=datadog - -Type=simple - -Environment=DD_APM_INSTRUMENTATION_DEBUG=TRUE -Environment=ASPNETCORE_URLS=http://+:5985 -Environment=DOTNET_DbgEnableMiniDump=1 -Environment=DOTNET_DbgMiniDumpType=4 -WorkingDirectory=/home/datadog/publish -ExecStart=/bin/bash -c 'dotnet MinimalWebApp.dll >> /home/datadog/app-std.out 2>&1 > /etc/environment' - sudo sh -c 'echo "DD_APM_INSTRUMENTATION_OUTPUT_PATHS=/opt/datadog/logs_injection/host_injection.log" >> /etc/environment' - source /etc/environment diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/Dockerfile.alpine b/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/Dockerfile.alpine deleted file mode 100644 index 360717db544..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/Dockerfile.alpine +++ /dev/null @@ -1,12 +0,0 @@ -FROM public.ecr.aws/docker/library/alpine:latest -RUN apk --no-cache add openjdk11 --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community -RUN apk add --no-cache bash -COPY build/libs/k8s-lib-injection-app-0.0.1-SNAPSHOT.jar /usr/local/app/ - -COPY docker_entrypoint_docker.sh /usr/local/app/ -RUN chmod 755 /usr/local/app/docker_entrypoint_docker.sh -CMD [ "/usr/local/app/docker_entrypoint_docker.sh" ] - - - - diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/Dockerfile.alpine-jdk15 b/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/Dockerfile.alpine-jdk15 deleted file mode 100644 index 43a78f817c4..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/Dockerfile.alpine-jdk15 +++ /dev/null @@ -1,8 +0,0 @@ -FROM public.ecr.aws/docker/library/alpine:3.18 -RUN apk add openjdk15-jdk - -COPY build/libs/k8s-lib-injection-app-0.0.1-SNAPSHOT.jar /usr/local/app/ - -WORKDIR /usr/local/app/ - -ENTRYPOINT ["java", "-jar", "k8s-lib-injection-app-0.0.1-SNAPSHOT.jar"] \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/Dockerfile.alpine-jdk21 b/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/Dockerfile.alpine-jdk21 deleted file mode 100644 index fa21a986746..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/Dockerfile.alpine-jdk21 +++ /dev/null @@ -1,11 +0,0 @@ -FROM public.ecr.aws/docker/library/alpine:latest -RUN apk --no-cache add openjdk21 --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community - -COPY build/libs/k8s-lib-injection-app-0.0.1-SNAPSHOT.jar /usr/local/app/ - -WORKDIR /usr/local/app/ -ENTRYPOINT ["java", "-jar", "k8s-lib-injection-app-0.0.1-SNAPSHOT.jar"] - - - - diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/Dockerfile.alpine.libgcc b/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/Dockerfile.alpine.libgcc deleted file mode 100644 index dd54e24417d..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/Dockerfile.alpine.libgcc +++ /dev/null @@ -1,13 +0,0 @@ -FROM public.ecr.aws/docker/library/alpine:latest -RUN apk --no-cache add openjdk11 --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community -RUN apk add libgcc -RUN apk add --no-cache bash -COPY build/libs/k8s-lib-injection-app-0.0.1-SNAPSHOT.jar /usr/local/app/ - -COPY docker_entrypoint_docker.sh /usr/local/app/ -RUN chmod 755 /usr/local/app/docker_entrypoint_docker.sh -CMD [ "/usr/local/app/docker_entrypoint_docker.sh" ] - - - - diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/docker-compose.yml b/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/docker-compose.yml deleted file mode 100644 index ce64d9cdc8e..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: '3' -services: - test-app-java: - container_name: test-app-java - image: system-tests/local:latest - ports: - - 5985:8080 diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/docker_entrypoint_docker.sh b/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/docker_entrypoint_docker.sh deleted file mode 100755 index d68ac027685..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/docker_entrypoint_docker.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -java -jar /usr/local/app/k8s-lib-injection-app-0.0.1-SNAPSHOT.jar diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/test-app-java_docker_compose_run.sh b/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/test-app-java_docker_compose_run.sh deleted file mode 100755 index d15faf5d467..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-alpine/test-app-java_docker_compose_run.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC2015 -set -e - -# shellcheck disable=SC2035 -sudo chmod -R 755 * - -rm -rf Dockerfile || true -cp Dockerfile.template Dockerfile || true - -./gradlew build -sudo docker build --no-cache -t system-tests/local . -if [ -f docker-compose-agent-prod.yml ]; then - # Agent may be installed in a different way - sudo -E docker-compose -f docker-compose-agent-prod.yml up -d --remove-orphans datadog - sleep 30 -fi -sudo -E docker-compose -f docker-compose.yml up -d test-app-java - -echo "**************** RUNNING DOCKER SERVICES *****************" -sudo docker-compose ps -if [ -f docker-compose-agent-prod.yml ]; then - echo "**************** DATADOG AGENT OUTPUT ********************" - sudo docker-compose -f docker-compose-agent-prod.yml logs datadog -fi -echo "**************** WEBLOG APP OUTPUT********************" -sudo docker-compose logs -echo "RUN DONE" diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-buildpack/docker-compose.yml b/utils/build/virtual_machine/weblogs/java/test-app-java-buildpack/docker-compose.yml deleted file mode 100644 index ce64d9cdc8e..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-buildpack/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: '3' -services: - test-app-java: - container_name: test-app-java - image: system-tests/local:latest - ports: - - 5985:8080 diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-buildpack/test-app-java_docker_compose_run_buildpack.sh b/utils/build/virtual_machine/weblogs/java/test-app-java-buildpack/test-app-java_docker_compose_run_buildpack.sh index 3d2bd84962c..6fcb0d1c24c 100755 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-buildpack/test-app-java_docker_compose_run_buildpack.sh +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-buildpack/test-app-java_docker_compose_run_buildpack.sh @@ -10,6 +10,8 @@ sudo chmod -R 755 * rm -rf Dockerfile || true +sudo systemctl start docker # Start docker service if it's not started + echo "**************** Docker system df *****************" sudo docker system df echo "**************** Disk usage *****************" @@ -19,11 +21,11 @@ sudo docker images echo "**************** Docker containers *****************" sudo docker ps -a echo "**************** Docker volumes *****************" -sudo docker volume ls +sudo docker volume ls echo "**************** BUILDING BUILDPACK *****************" sudo ./gradlew build -sudo ./gradlew -PdockerImageRepo=system-tests/local -PdockerImageTag=latest clean bootBuildImage +sudo ./gradlew -PdockerImageRepo=system-tests/local -PdockerImageTag=latest -PuseDockerProxy=true clean bootBuildImage echo "**************** RUN SERVICES*****************" if [ -f docker-compose-agent-prod.yml ]; then @@ -31,7 +33,16 @@ if [ -f docker-compose-agent-prod.yml ]; then sudo -E docker-compose -f docker-compose-agent-prod.yml up -d --remove-orphans datadog sleep 30 fi -sudo -E docker-compose -f docker-compose.yml up -d test-app-java +#Env variables set on the scenario definition. Write to file and load +if [ ! -f scenario_app.env ] +then + SCENARIO_APP_ENV="${DD_APP_ENV:-''}" + echo "$SCENARIO_APP_ENV" | tr '[:space:]' '\n' > scenario_app.env + echo "APP VARIABLES CONFIGURED FROM THE SCENARIO:" + cat scenario_app.env +fi +echo "SERVER_PORT=18080" >> scenario_app.env +sudo -E docker-compose -f docker-compose.yml up -d test-app echo "**************** RUNNING DOCKER SERVICES *****************" sudo docker-compose ps diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-container/Dockerfile.jdk11 b/utils/build/virtual_machine/weblogs/java/test-app-java-container/Dockerfile.jdk11 deleted file mode 100644 index bdb712fb2cb..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-container/Dockerfile.jdk11 +++ /dev/null @@ -1,9 +0,0 @@ -FROM public.ecr.aws/docker/library/openjdk:11 - -COPY build/libs/k8s-lib-injection-app-0.0.1-SNAPSHOT.jar /usr/local/app/ - -WORKDIR /usr/local/app/ -ENTRYPOINT ["java", "-jar", "k8s-lib-injection-app-0.0.1-SNAPSHOT.jar"] - - - diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-container/Dockerfile.jdk15 b/utils/build/virtual_machine/weblogs/java/test-app-java-container/Dockerfile.jdk15 deleted file mode 100644 index 7434a1af45b..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-container/Dockerfile.jdk15 +++ /dev/null @@ -1,11 +0,0 @@ -FROM public.ecr.aws/docker/library/openjdk:15 - -COPY build/libs/k8s-lib-injection-app-0.0.1-SNAPSHOT.jar /usr/local/app/ - -COPY docker_entrypoint_docker.sh /usr/local/app/ -RUN chmod 755 /usr/local/app/docker_entrypoint_docker.sh -CMD [ "/usr/local/app/docker_entrypoint_docker.sh" ] - - - - diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-container/docker-compose.yml b/utils/build/virtual_machine/weblogs/java/test-app-java-container/docker-compose.yml deleted file mode 100644 index ce64d9cdc8e..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-container/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: '3' -services: - test-app-java: - container_name: test-app-java - image: system-tests/local:latest - ports: - - 5985:8080 diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-container/docker_entrypoint_docker.sh b/utils/build/virtual_machine/weblogs/java/test-app-java-container/docker_entrypoint_docker.sh deleted file mode 100755 index d68ac027685..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-container/docker_entrypoint_docker.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -java -jar /usr/local/app/k8s-lib-injection-app-0.0.1-SNAPSHOT.jar diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-container/test-app-java_docker_compose_run.sh b/utils/build/virtual_machine/weblogs/java/test-app-java-container/test-app-java_docker_compose_run.sh deleted file mode 100755 index 4d925af98c5..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java-container/test-app-java_docker_compose_run.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC2015 -set -e - -# shellcheck disable=SC2035 -sudo chmod -R 755 * -rm -rf Dockerfile || true -cp Dockerfile.template Dockerfile || true -ls -la -./gradlew build -sudo docker build --no-cache -t system-tests/local . -if [ -f docker-compose-agent-prod.yml ]; then - # Agent may be installed in a different way - sudo -E docker-compose -f docker-compose-agent-prod.yml up -d --remove-orphans datadog - sleep 30 -fi -sudo -E docker-compose -f docker-compose.yml up -d test-app-java - -echo "**************** RUNNING DOCKER SERVICES *****************" -sudo docker-compose ps -if [ -f docker-compose-agent-prod.yml ]; then - echo "**************** DATADOG AGENT OUTPUT ********************" - sudo docker-compose -f docker-compose-agent-prod.yml logs datadog -fi -echo "**************** WEBLOG APP OUTPUT********************" -sudo docker-compose logs -echo "RUN DONE" diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk11-alpine b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk11-alpine new file mode 100644 index 00000000000..9ff235e647e --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk11-alpine @@ -0,0 +1,10 @@ +FROM public.ecr.aws/docker/library/alpine:latest +RUN apk --no-cache add openjdk11 +RUN apk add --no-cache bash curl + +COPY jetty-classpath/. /opt/jetty-classpath +COPY JettyServletMain.class /usr/local/app/ +COPY CrashServlet.class /usr/local/app/ +COPY run_app.sh /usr/local/app/ +WORKDIR /usr/local/app/ +ENTRYPOINT ["/usr/local/app/run_app.sh"] diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk15-alpine b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk15-alpine new file mode 100644 index 00000000000..b3bb4b59bcf --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk15-alpine @@ -0,0 +1,10 @@ +FROM public.ecr.aws/docker/library/alpine:3.18 +RUN apk --no-cache add openjdk15-jdk +RUN apk add --no-cache bash curl + +COPY jetty-classpath/. /opt/jetty-classpath +COPY JettyServletMain.class /usr/local/app/ +COPY CrashServlet.class /usr/local/app/ +COPY run_app.sh /usr/local/app/ +WORKDIR /usr/local/app/ +ENTRYPOINT ["/usr/local/app/run_app.sh"] diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk17-alpine b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk17-alpine new file mode 100644 index 00000000000..4b663dcac8f --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk17-alpine @@ -0,0 +1,10 @@ +FROM public.ecr.aws/docker/library/alpine:latest +RUN apk --no-cache add openjdk17 +RUN apk add --no-cache bash curl + +COPY jetty-classpath/. /opt/jetty-classpath +COPY JettyServletMain.class /usr/local/app/ +COPY CrashServlet.class /usr/local/app/ +COPY run_app.sh /usr/local/app/ +WORKDIR /usr/local/app/ +ENTRYPOINT ["/usr/local/app/run_app.sh"] diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk21-alpine b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk21-alpine new file mode 100644 index 00000000000..18e0156320e --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk21-alpine @@ -0,0 +1,10 @@ +FROM public.ecr.aws/docker/library/alpine:latest +RUN apk --no-cache add openjdk21 +RUN apk add --no-cache bash curl + +COPY jetty-classpath/. /opt/jetty-classpath +COPY JettyServletMain.class /usr/local/app/ +COPY CrashServlet.class /usr/local/app/ +COPY run_app.sh /usr/local/app/ +WORKDIR /usr/local/app/ +ENTRYPOINT ["/usr/local/app/run_app.sh"] diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk8-alpine b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk8-alpine new file mode 100644 index 00000000000..86526542c44 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.jdk8-alpine @@ -0,0 +1,10 @@ +FROM public.ecr.aws/docker/library/alpine:latest +RUN apk --no-cache add openjdk8 +RUN apk add --no-cache bash curl + +COPY jetty-classpath/. /opt/jetty-classpath +COPY JettyServletMain.class /usr/local/app/ +COPY CrashServlet.class /usr/local/app/ +COPY run_app.sh /usr/local/app/ +WORKDIR /usr/local/app/ +ENTRYPOINT ["/usr/local/app/run_app.sh"] diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.reverseproxy b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.reverseproxy new file mode 100644 index 00000000000..82cdb622233 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/Dockerfile.reverseproxy @@ -0,0 +1,3 @@ +FROM public.ecr.aws/nginx/nginx:stable-perl + +COPY nginx.conf /etc/nginx/nginx.conf \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/docker-compose.yml b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/docker-compose.yml new file mode 100644 index 00000000000..15d5763de8e --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/docker-compose.yml @@ -0,0 +1,61 @@ +version: '3' +services: + reverseproxy: + image: reverseproxy:latest + ports: + - 5985:8080 + restart: always + build: + context: . + dockerfile: Dockerfile.reverseproxy + healthcheck: + test: "curl -f http://localhost:8080" + java_8_alpine: + env_file: "scenario_app.env" + image: system-tests/java_8_alpine:latest + restart: always + build: + context: . + dockerfile: Dockerfile.jdk8-alpine + healthcheck: + test: "curl -f http://localhost:18080" + + java_11_alpine: + env_file: "scenario_app.env" + image: system-tests/java_11_alpine:latest + restart: always + build: + context: . + dockerfile: Dockerfile.jdk11-alpine + healthcheck: + test: "curl -f http://localhost:18080" + + java_15_alpine: + env_file: "scenario_app.env" + image: system-tests/java_15_alpine:latest + restart: always + build: + context: . + dockerfile: Dockerfile.jdk15-alpine + healthcheck: + test: "curl -f http://localhost:18080" + + java_17_alpine: + env_file: "scenario_app.env" + image: system-tests/java_17_alpine:latest + restart: always + build: + context: . + dockerfile: Dockerfile.jdk17-alpine + healthcheck: + test: "curl -f http://localhost:18080" + + java_21_alpine: + env_file: "scenario_app.env" + image: system-tests/java_21_alpine:latest + restart: always + build: + context: . + dockerfile: Dockerfile.jdk21-alpine + healthcheck: + test: "curl -f http://localhost:18080" diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/nginx.conf b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/nginx.conf new file mode 100644 index 00000000000..5d3b7ec0ac3 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multialpine/nginx.conf @@ -0,0 +1,65 @@ +worker_processes 1; + +events { worker_connections 1024; } + +http { + + log_format compression '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $upstream_addr ' + '"$http_referer" "$http_user_agent" "$gzip_ratio"'; + + server { + listen 8080; + access_log /var/log/nginx/access.log compression; + + location / { + default_type application/json; + return 200 "{ + 'app_type':'multicontainer', + 'apps':[{ + 'runtime':'8', + 'type':'alpine', + 'url':'/java_8_alpine/' + },{ + 'runtime':'11', + 'type':'alpine', + 'url':'/java_11_alpine/' + },{ + 'runtime':'15', + 'type':'alpine', + 'url':'/java_15_alpine/' + },{ + 'runtime':'17', + 'type':'alpine', + 'url':'/java_17_alpine/' + },{ + 'runtime':'21', + 'type':'alpine', + 'url':'/java_21_alpine/' + } + ] + }"; + } + + location /java_8_alpine/ { + proxy_pass http://java_8_alpine:18080/; + proxy_redirect off; + } + location /java_11_alpine/ { + proxy_pass http://java_11_alpine:18080/; + proxy_redirect off; + } + location /java_15_alpine/ { + proxy_pass http://java_15_alpine:18080/; + proxy_redirect off; + } + location /java_17_alpine/ { + proxy_pass http://java_17_alpine:18080/; + proxy_redirect off; + } + location /java_21_alpine/ { + proxy_pass http://java_21_alpine:18080/; + proxy_redirect off; + } + } +} \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk11 b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk11 new file mode 100644 index 00000000000..0cf6cfc8086 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk11 @@ -0,0 +1,8 @@ +FROM public.ecr.aws/docker/library/openjdk:11 + +COPY jetty-classpath/. /opt/jetty-classpath +COPY JettyServletMain.class /usr/local/app/ +COPY CrashServlet.class /usr/local/app/ +COPY run_app.sh /usr/local/app/ +WORKDIR /usr/local/app/ +ENTRYPOINT ["/usr/local/app/run_app.sh"] diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk15 b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk15 new file mode 100644 index 00000000000..ed3461410d9 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk15 @@ -0,0 +1,8 @@ +FROM public.ecr.aws/docker/library/openjdk:15 + +COPY jetty-classpath/. /opt/jetty-classpath +COPY JettyServletMain.class /usr/local/app/ +COPY CrashServlet.class /usr/local/app/ +COPY run_app.sh /usr/local/app/ +WORKDIR /usr/local/app/ +ENTRYPOINT ["/usr/local/app/run_app.sh"] diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk17 b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk17 new file mode 100644 index 00000000000..a42fa68f941 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk17 @@ -0,0 +1,8 @@ +FROM public.ecr.aws/docker/library/openjdk:17 + +COPY jetty-classpath/. /opt/jetty-classpath +COPY JettyServletMain.class /usr/local/app/ +COPY CrashServlet.class /usr/local/app/ +COPY run_app.sh /usr/local/app/ +WORKDIR /usr/local/app/ +ENTRYPOINT ["/usr/local/app/run_app.sh"] diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk21 b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk21 new file mode 100644 index 00000000000..14505f595c7 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk21 @@ -0,0 +1,8 @@ +FROM public.ecr.aws/docker/library/openjdk:21 + +COPY jetty-classpath/. /opt/jetty-classpath +COPY JettyServletMain.class /usr/local/app/ +COPY CrashServlet.class /usr/local/app/ +COPY run_app.sh /usr/local/app/ +WORKDIR /usr/local/app/ +ENTRYPOINT ["/usr/local/app/run_app.sh"] diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk8 b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk8 new file mode 100644 index 00000000000..7f89ccc4364 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.jdk8 @@ -0,0 +1,8 @@ +FROM public.ecr.aws/docker/library/openjdk:8 + +COPY jetty-classpath/. /opt/jetty-classpath +COPY JettyServletMain.class /usr/local/app/ +COPY CrashServlet.class /usr/local/app/ +COPY run_app.sh /usr/local/app/ +WORKDIR /usr/local/app/ +ENTRYPOINT ["/usr/local/app/run_app.sh"] diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.reverseproxy b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.reverseproxy new file mode 100644 index 00000000000..82cdb622233 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/Dockerfile.reverseproxy @@ -0,0 +1,3 @@ +FROM public.ecr.aws/nginx/nginx:stable-perl + +COPY nginx.conf /etc/nginx/nginx.conf \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/docker-compose.yml b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/docker-compose.yml new file mode 100644 index 00000000000..4fff7ac7dd1 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/docker-compose.yml @@ -0,0 +1,61 @@ +version: '3' +services: + reverseproxy: + image: reverseproxy:latest + ports: + - 5985:8080 + restart: always + build: + context: . + dockerfile: Dockerfile.reverseproxy + healthcheck: + test: "curl -f http://localhost:8080" + java_8: + env_file: "scenario_app.env" + image: system-tests/java_8:latest + restart: always + build: + context: . + dockerfile: Dockerfile.jdk8 + healthcheck: + test: "curl -f http://localhost:18080" + + java_11: + env_file: "scenario_app.env" + image: system-tests/java_11:latest + restart: always + build: + context: . + dockerfile: Dockerfile.jdk11 + healthcheck: + test: "curl -f http://localhost:18080" + + java_15: + env_file: "scenario_app.env" + image: system-tests/java_15:latest + restart: always + build: + context: . + dockerfile: Dockerfile.jdk15 + healthcheck: + test: "curl -f http://localhost:18080" + + java_17: + env_file: "scenario_app.env" + image: system-tests/java_17:latest + restart: always + build: + context: . + dockerfile: Dockerfile.jdk17 + healthcheck: + test: "curl -f http://localhost:18080" + + java_21: + env_file: "scenario_app.env" + image: system-tests/java_21:latest + restart: always + build: + context: . + dockerfile: Dockerfile.jdk21 + healthcheck: + test: "curl -f http://localhost:18080" diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/nginx.conf b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/nginx.conf new file mode 100644 index 00000000000..b2498feb726 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java-multicontainer/nginx.conf @@ -0,0 +1,64 @@ +worker_processes 1; + +events { worker_connections 1024; } + +http { + + log_format compression '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $upstream_addr ' + '"$http_referer" "$http_user_agent" "$gzip_ratio"'; + + server { + listen 8080; + access_log /var/log/nginx/access.log compression; + + location / { + default_type application/json; + return 200 "{ + 'app_type':'multicontainer', + 'apps':[{ + 'runtime':'8', + 'type':'container', + 'url':'/java_8/' + },{ + 'runtime':'11', + 'type':'container', + 'url':'/java_11/' + },{ + 'runtime':'15', + 'type':'container', + 'url':'/java_15/' + },{ + 'runtime':'17', + 'type':'container', + 'url':'/java_17/' + },{ + 'runtime':'21', + 'type':'container', + 'url':'/java_21/' + } + ] + }"; + } + location /java_8/ { + proxy_pass http://java_8:18080/; + proxy_redirect off; + } + location /java_11/ { + proxy_pass http://java_11:18080/; + proxy_redirect off; + } + location /java_15/ { + proxy_pass http://java_15:18080/; + proxy_redirect off; + } + location /java_17/ { + proxy_pass http://java_17:18080/; + proxy_redirect off; + } + location /java_21/ { + proxy_pass http://java_21:18080/; + proxy_redirect off; + } + } +} \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java/compile_app.sh b/utils/build/virtual_machine/weblogs/java/test-app-java/compile_app.sh new file mode 100755 index 00000000000..ee9ea396649 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java/compile_app.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -e + +# shellcheck disable=SC2035 +sudo chmod -R 755 * + +echo "Compiling Java app" +JETTY_VERSION=9.4.56.v20240826 +JETTY_FILE="jetty-distribution-$JETTY_VERSION.tar.gz" +PORT=$1 +if [ -f "$JETTY_FILE" ]; then + echo "Jetty already downloaded." +else + echo "Downloading Jetty runtime" + wget -q https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-distribution/$JETTY_VERSION/jetty-distribution-$JETTY_VERSION.tar.gz + sudo tar -xf jetty-distribution-$JETTY_VERSION.tar.gz -C /opt/ +fi + +mkdir -p jetty-classpath + +find /opt/jetty-distribution-$JETTY_VERSION/lib -iname '*.jar' -exec cp \{\} jetty-classpath/ \; + +# Causes ClassNotFound exceptions https://github.com/jetty/jetty.project/issues/4746 +rm jetty-classpath/jetty-jaspi* + +FILE=JettyServletMain.class +if [ -f "$FILE" ]; then + echo "App already compiled." +else + sudo sed -i "s/18080/$PORT/g" JettyServletMain.java + javac -cp "jetty-classpath/*:." JettyServletMain.java CrashServlet.java + sudo cp JettyServletMain.class /home/datadog + sudo cp CrashServlet.class /home/datadog +fi + +echo "Compiling Java app DONE" \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java/run_app.sh b/utils/build/virtual_machine/weblogs/java/test-app-java/run_app.sh new file mode 100755 index 00000000000..ec374f02178 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/java/test-app-java/run_app.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -e + +JETTY_CLASSPATH="/opt/jetty-classpath/*:." +java -cp "$JETTY_CLASSPATH" JettyServletMain diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java/test-app-java_run.sh b/utils/build/virtual_machine/weblogs/java/test-app-java/test-app-java_run.sh index 77267c85198..76baa8f0a8d 100755 --- a/utils/build/virtual_machine/weblogs/java/test-app-java/test-app-java_run.sh +++ b/utils/build/virtual_machine/weblogs/java/test-app-java/test-app-java_run.sh @@ -4,17 +4,15 @@ set -e # shellcheck disable=SC2035 sudo chmod -R 755 * -echo "START RUN APP" -./gradlew build +echo "Start Java app" +./compile_app.sh 5985 +sudo mkdir -p /opt/jetty-classpath +sudo cp -r jetty-classpath/. /opt/jetty-classpath -sudo cp build/libs/k8s-lib-injection-app-0.0.1-SNAPSHOT.jar /home/datadog -sudo cp test-app.service /etc/systemd/system/test-app.service -sudo systemctl daemon-reload -sudo systemctl enable test-app.service -sudo systemctl start test-app.service -sudo systemctl status test-app.service -sleep 5 -sudo cat /home/datadog/app-std.out +sudo chmod 755 create_and_run_app_service.sh -echo "RUN DONE" \ No newline at end of file +JETTY_CLASSPATH="/opt/jetty-classpath/*:." +./create_and_run_app_service.sh "java -cp $JETTY_CLASSPATH JettyServletMain" + +echo " Java app started DONE" diff --git a/utils/build/virtual_machine/weblogs/java/test-app-java/test-app.service b/utils/build/virtual_machine/weblogs/java/test-app-java/test-app.service deleted file mode 100644 index 9dbf50bede0..00000000000 --- a/utils/build/virtual_machine/weblogs/java/test-app-java/test-app.service +++ /dev/null @@ -1,19 +0,0 @@ -[Unit] -Description=Java Weblog App Service -After=syslog.target network.target - -[Service] -SuccessExitStatus=143 - -User=datadog - -Type=simple - -Environment=DD_APM_INSTRUMENTATION_DEBUG=TRUE -Environment=DD_CONFIG_SOURCES=LOCAL:/etc/datadog-agent/inject/debug_config.yaml -WorkingDirectory=/home/datadog -ExecStart=/bin/bash -c 'java -Dserver.port=5985 -jar k8s-lib-injection-app-0.0.1-SNAPSHOT.jar >> /home/datadog/app-std.out 2>&1 > /etc/environment' - sudo sh -c 'echo "DD_APM_INSTRUMENTATION_OUTPUT_PATHS=/opt/datadog/logs_injection/host_injection.log" >> /etc/environment' - source /etc/environment diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-alpine/Dockerfile.libgcc.template b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-alpine/Dockerfile.libgcc.template deleted file mode 100644 index 98debcc7854..00000000000 --- a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-alpine/Dockerfile.libgcc.template +++ /dev/null @@ -1,17 +0,0 @@ -FROM public.ecr.aws/docker/library/alpine:latest - -RUN apk add --update nodejs npm -RUN apk add libgcc -RUN apk add --no-cache bash -RUN addgroup -S node && adduser -S node -G node - -USER node - -RUN mkdir /home/node/code - -WORKDIR /home/node/code - -COPY --chown=node:node . . - -EXPOSE 18080 -CMD ["node", "index.js"] \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-alpine/Dockerfile.template b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-alpine/Dockerfile.template index 1e0056a57b3..3f81000b884 100644 --- a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-alpine/Dockerfile.template +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-alpine/Dockerfile.template @@ -13,4 +13,4 @@ WORKDIR /home/node/code COPY --chown=node:node . . EXPOSE 18080 -CMD ["node", "index.js"] \ No newline at end of file +CMD ["node", "index.js"] diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-alpine/docker-compose.yml b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-alpine/docker-compose.yml deleted file mode 100644 index 2784271ebd1..00000000000 --- a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-alpine/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: '3' -services: - test-app-nodejs: - container_name: test-app-nodejs - image: system-tests/local:latest - ports: - - 5985:18080 diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-alpine/test-app-nodejs_docker_compose_run.sh b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-alpine/test-app-nodejs_docker_compose_run.sh deleted file mode 100755 index 9ba54230cad..00000000000 --- a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-alpine/test-app-nodejs_docker_compose_run.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC2015 - -set -e - -# shellcheck disable=SC2035 -sudo chmod -R 755 * - -rm -rf Dockerfile || true -cp Dockerfile.template Dockerfile || true - -echo "Starting nodejs app deployment" -sudo docker build --no-cache -t system-tests/local . -if [ -f docker-compose-agent-prod.yml ]; then - # Agent may be installed in a different way - sudo -E docker-compose -f docker-compose-agent-prod.yml up -d --remove-orphans datadog - sleep 30 -fi -sudo -E docker-compose -f docker-compose.yml up -d test-app-nodejs - -echo "**************** RUNNING DOCKER SERVICES *****************" -sudo docker-compose ps -if [ -f docker-compose-agent-prod.yml ]; then - echo "**************** DATADOG AGENT OUTPUT ********************" - sudo docker-compose -f docker-compose-agent-prod.yml logs datadog -fi -echo "**************** WEBLOG APP OUTPUT********************" -sudo docker-compose logs -echo "RUN DONE!" diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-container/docker-compose.yml b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-container/docker-compose.yml deleted file mode 100644 index 2784271ebd1..00000000000 --- a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-container/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: '3' -services: - test-app-nodejs: - container_name: test-app-nodejs - image: system-tests/local:latest - ports: - - 5985:18080 diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-container/test-app-nodejs_docker_compose_run.sh b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-container/test-app-nodejs_docker_compose_run.sh deleted file mode 100755 index 9ba54230cad..00000000000 --- a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-container/test-app-nodejs_docker_compose_run.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC2015 - -set -e - -# shellcheck disable=SC2035 -sudo chmod -R 755 * - -rm -rf Dockerfile || true -cp Dockerfile.template Dockerfile || true - -echo "Starting nodejs app deployment" -sudo docker build --no-cache -t system-tests/local . -if [ -f docker-compose-agent-prod.yml ]; then - # Agent may be installed in a different way - sudo -E docker-compose -f docker-compose-agent-prod.yml up -d --remove-orphans datadog - sleep 30 -fi -sudo -E docker-compose -f docker-compose.yml up -d test-app-nodejs - -echo "**************** RUNNING DOCKER SERVICES *****************" -sudo docker-compose ps -if [ -f docker-compose-agent-prod.yml ]; then - echo "**************** DATADOG AGENT OUTPUT ********************" - sudo docker-compose -f docker-compose-agent-prod.yml logs datadog -fi -echo "**************** WEBLOG APP OUTPUT********************" -sudo docker-compose logs -echo "RUN DONE!" diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/Dockerfile.node b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/Dockerfile.node new file mode 100644 index 00000000000..bf98f10942a --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/Dockerfile.node @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/node:20-slim + +# Create app directory +WORKDIR /usr/src/app + +COPY . . + +EXPOSE 18080 +CMD [ "node", "index.mjs" ] diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/Dockerfile.node20 b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/Dockerfile.node20 new file mode 100644 index 00000000000..bf98f10942a --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/Dockerfile.node20 @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/node:20-slim + +# Create app directory +WORKDIR /usr/src/app + +COPY . . + +EXPOSE 18080 +CMD [ "node", "index.mjs" ] diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/Dockerfile.reverseproxy b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/Dockerfile.reverseproxy new file mode 100644 index 00000000000..f131f6f168b --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/Dockerfile.reverseproxy @@ -0,0 +1,3 @@ +FROM public.ecr.aws/nginx/nginx:stable-perl + +COPY nginx.conf /etc/nginx/nginx.conf diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/docker-compose.yml b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/docker-compose.yml new file mode 100644 index 00000000000..c9c1d9a476f --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/docker-compose.yml @@ -0,0 +1,33 @@ +version: '2' + +services: + reverseproxy: + image: reverseproxy:latest + ports: + - 5985:8080 + restart: always + build: + context: . + dockerfile: Dockerfile.reverseproxy + healthcheck: + test: "curl -f http://localhost:8080" + + node_20: + env_file: "scenario_app.env" + image: system-tests/node_20:latest + restart: always + build: + context: . + dockerfile: Dockerfile.node20 + healthcheck: + test: "node health" + + node: + env_file: "scenario_app.env" + image: system-tests/node:latest + restart: always + build: + context: . + dockerfile: Dockerfile.node + healthcheck: + test: "node health" diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/nginx.conf b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/nginx.conf new file mode 100644 index 00000000000..f7c3522ab52 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-esm/nginx.conf @@ -0,0 +1,47 @@ +worker_processes 1; + +events { worker_connections 1024; } + +http { + + log_format compression '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $upstream_addr ' + '"$http_referer" "$http_user_agent" "$gzip_ratio"'; + + upstream node_20_app { + server node_20:18080; + } + upstream node_app { + server node:18080; + } + + server { + listen 8080; + access_log /var/log/nginx/access.log compression; + + location / { + default_type application/json; + return 200 "{ + 'app_type':'multicontainer', + 'apps':[{ + 'runtime':'20', + 'type':'container', + 'url':'/node_20/' + },{ + 'runtime':'latest', + 'type':'container', + 'url':'/node/' + }] + }"; + } + + location /node_20/ { + proxy_pass http://node_20_app/; + proxy_redirect off; + } + location /node/ { + proxy_pass http://node_app/; + proxy_redirect off; + } + } +} diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.alpine b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.alpine new file mode 100644 index 00000000000..4438e8c013e --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.alpine @@ -0,0 +1,16 @@ +FROM public.ecr.aws/docker/library/alpine:latest + +RUN apk add --update nodejs npm +RUN apk add --no-cache bash curl +RUN addgroup -S node && adduser -S node -G node + +USER node + +RUN mkdir /home/node/code + +WORKDIR /home/node/code + +COPY --chown=node:node . . + +EXPOSE 18080 +CMD ["node", "index.js"] diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node new file mode 100644 index 00000000000..fc1efde4b99 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/node + +# Create app directory +WORKDIR /usr/src/app + +COPY . . + +EXPOSE 18080 +CMD [ "node", "index.js" ] diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node-alpine b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node-alpine new file mode 100644 index 00000000000..19cc45ae409 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node-alpine @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/node:alpine + +# Create app directory +WORKDIR /usr/src/app + +COPY . . + +EXPOSE 18080 +CMD [ "node", "index.js" ] diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node18 b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node18 new file mode 100644 index 00000000000..d507c19c5bb --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node18 @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/node:18-slim + +# Create app directory +WORKDIR /usr/src/app + +COPY . . + +EXPOSE 18080 +CMD [ "node", "index.js" ] diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node18-alpine b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node18-alpine new file mode 100644 index 00000000000..e05d241d6dc --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node18-alpine @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/node:18-alpine + +# Create app directory +WORKDIR /usr/src/app + +COPY . . + +EXPOSE 18080 +CMD [ "node", "index.js" ] diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node20 b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node20 new file mode 100644 index 00000000000..936a126a080 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node20 @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/node:20-slim + +# Create app directory +WORKDIR /usr/src/app + +COPY . . + +EXPOSE 18080 +CMD [ "node", "index.js" ] diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node20-alpine b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node20-alpine new file mode 100644 index 00000000000..f82c3494396 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node20-alpine @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/node:20-alpine + +# Create app directory +WORKDIR /usr/src/app + +COPY . . + +EXPOSE 18080 +CMD [ "node", "index.js" ] diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node22 b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node22 new file mode 100644 index 00000000000..965b488b633 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node22 @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/node:22-slim + +# Create app directory +WORKDIR /usr/src/app + +COPY . . + +EXPOSE 18080 +CMD [ "node", "index.js" ] diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node22-alpine b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node22-alpine new file mode 100644 index 00000000000..b1a5f4132fe --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.node22-alpine @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/node:22-alpine + +# Create app directory +WORKDIR /usr/src/app + +COPY . . + +EXPOSE 18080 +CMD [ "node", "index.js" ] diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.reverseproxy b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.reverseproxy new file mode 100644 index 00000000000..f131f6f168b --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/Dockerfile.reverseproxy @@ -0,0 +1,3 @@ +FROM public.ecr.aws/nginx/nginx:stable-perl + +COPY nginx.conf /etc/nginx/nginx.conf diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/docker-compose.yml b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/docker-compose.yml new file mode 100644 index 00000000000..425d7703247 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/docker-compose.yml @@ -0,0 +1,93 @@ +version: '2' + +services: + reverseproxy: + image: reverseproxy:latest + ports: + - 5985:8080 + restart: always + build: + context: . + dockerfile: Dockerfile.reverseproxy + healthcheck: + test: "curl -f http://localhost:8080" + + node_18: + env_file: "scenario_app.env" + image: system-tests/node_18:latest + restart: always + build: + context: . + dockerfile: Dockerfile.node18 + healthcheck: + test: "node health" + + node_20: + env_file: "scenario_app.env" + image: system-tests/node_20:latest + restart: always + build: + context: . + dockerfile: Dockerfile.node20 + healthcheck: + test: "node health" + + node_22: + env_file: "scenario_app.env" + image: system-tests/node_22:latest + restart: always + build: + context: . + dockerfile: Dockerfile.node22 + healthcheck: + test: "node health" + + node: + env_file: "scenario_app.env" + image: system-tests/node:latest + restart: always + build: + context: . + dockerfile: Dockerfile.node + healthcheck: + test: "node health" + + node_18_alpine: + env_file: "scenario_app.env" + image: system-tests/node_18_alpine:latest + restart: always + build: + context: . + dockerfile: Dockerfile.node18-alpine + healthcheck: + test: "node health" + + node_20_alpine: + env_file: "scenario_app.env" + image: system-tests/node_20_alpine:latest + restart: always + build: + context: . + dockerfile: Dockerfile.node20-alpine + healthcheck: + test: "node health" + + node_22_alpine: + env_file: "scenario_app.env" + image: system-tests/node_22_alpine:latest + restart: always + build: + context: . + dockerfile: Dockerfile.node22-alpine + healthcheck: + test: "node health" + + node_alpine: + env_file: "scenario_app.env" + image: system-tests/node_alpine:latest + restart: always + build: + context: . + dockerfile: Dockerfile.node-alpine + healthcheck: + test: "node health" diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/nginx.conf b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/nginx.conf new file mode 100644 index 00000000000..d5f882597d0 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-multicontainer/nginx.conf @@ -0,0 +1,116 @@ +worker_processes 1; + +events { worker_connections 1024; } + + +http { + + log_format compression '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $upstream_addr ' + '"$http_referer" "$http_user_agent" "$gzip_ratio"'; + + upstream node_18_app { + server node_18:18080; + } + upstream node_20_app { + server node_20:18080; + } + upstream node_22_app { + server node_22:18080; + } + upstream node_app { + server node:18080; + } + + upstream node_18_alpine_app { + server node_18_alpine:18080; + } + upstream node_20_alpine_app { + server node_20_alpine:18080; + } + upstream node_22_alpine_app { + server node_22_alpine:18080; + } + upstream node_alpine_app { + server node_alpine:18080; + } + + server { + listen 8080; + access_log /var/log/nginx/access.log compression; + + location / { + default_type application/json; + return 200 "{ + 'app_type':'multicontainer', + 'apps':[{ + 'runtime':'18', + 'type':'container', + 'url':'/node_18/' + },{ + 'runtime':'20', + 'type':'container', + 'url':'/node_20/' + },{ + 'runtime':'22', + 'type':'container', + 'url':'/node_22/' + },{ + 'runtime':'latest', + 'type':'container', + 'url':'/node/' + },{ + 'runtime':'18', + 'type':'alpine', + 'url':'/node_18_alpine/' + },{ + 'runtime':'20', + 'type':'alpine', + 'url':'/node_20_alpine/' + },{ + 'runtime':'22', + 'type':'alpine', + 'url':'/node_22_alpine/' + },{ + 'runtime':'latest', + 'type':'alpine', + 'url':'/node_alpine/' + }] + }"; + } + + location /node_18/ { + proxy_pass http://node_18_app/; + proxy_redirect off; + } + location /node_20/ { + proxy_pass http://node_20_app/; + proxy_redirect off; + } + location /node_22/ { + proxy_pass http://node_22_app/; + proxy_redirect off; + } + location /node/ { + proxy_pass http://node_app/; + proxy_redirect off; + } + + location /node_18_alpine/ { + proxy_pass http://node_18_alpine_app/; + proxy_redirect off; + } + location /node_20_alpine/ { + proxy_pass http://node_20_alpine_app/; + proxy_redirect off; + } + location /node_22_alpine/ { + proxy_pass http://node_22_alpine_app/; + proxy_redirect off; + } + location /node_alpine/ { + proxy_pass http://node_alpine_app/; + proxy_redirect off; + } + } +} diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-profiling/test-app-nodejs_run.sh b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-profiling/test-app-nodejs_run.sh deleted file mode 100755 index e740a9eb2c1..00000000000 --- a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-profiling/test-app-nodejs_run.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -echo "START RUN APP" - - -sudo sed -i "s/18080/5985/g" index.js -sudo cp index.js /home/datadog -sudo cp test-app.service /etc/systemd/system/test-app.service -sudo systemctl daemon-reload -sudo systemctl enable test-app.service -sudo systemctl start test-app.service -sudo systemctl status test-app.service - -echo "RUN DONE" \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-profiling/test-app.service b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-profiling/test-app.service deleted file mode 100644 index 7b70c62e956..00000000000 --- a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs-profiling/test-app.service +++ /dev/null @@ -1,21 +0,0 @@ -[Unit] -Description=Nodejs Weblog App Service -After=syslog.target network.target - -[Service] -SuccessExitStatus=143 - -User=datadog - -Type=simple - -Environment=DD_APM_INSTRUMENTATION_DEBUG=TRUE -Environment=DD_PROFILING_ENABLED=auto -Environment=DD_PROFILING_UPLOAD_PERIOD=10 -Environment=DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD=1500 -WorkingDirectory=/home/datadog -ExecStart=/bin/bash -c 'node index.js' -ExecStop=/bin/kill -15 $MAINPID - -[Install] -WantedBy=multi-user.target diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs/test-app-nodejs_run.sh b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs/test-app-nodejs_run.sh index 17923d89bd8..dadcf9c472c 100755 --- a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs/test-app-nodejs_run.sh +++ b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs/test-app-nodejs_run.sh @@ -1,15 +1,8 @@ #!/bin/bash -echo "START RUN APP" - +echo "START nodejs APP" sudo sed -i "s/18080/5985/g" index.js sudo cp index.js /home/datadog -sudo cp test-app.service /etc/systemd/system/test-app.service -sudo systemctl daemon-reload -sudo systemctl enable test-app.service -sudo systemctl start test-app.service -sudo systemctl status test-app.service -sleep 5 -sudo cat /home/datadog/app-std.out - -echo "RUN DONE" \ No newline at end of file +sudo chmod 755 create_and_run_app_service.sh +./create_and_run_app_service.sh "node index.js" +echo "RUN nodejs DONE" \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs/test-app.service b/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs/test-app.service deleted file mode 100644 index 03d2d4e12b4..00000000000 --- a/utils/build/virtual_machine/weblogs/nodejs/test-app-nodejs/test-app.service +++ /dev/null @@ -1,22 +0,0 @@ -[Unit] -Description=Nodejs Weblog App Service -After=syslog.target network.target - -[Service] -SuccessExitStatus=143 - -User=datadog - -Type=simple - -Environment=DD_APM_INSTRUMENTATION_DEBUG=TRUE -Environment=DD_TRACE_DEBUG=true -Environment=DD_PROFILING_UPLOAD_PERIOD=10 -Environment=DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD=1500 -EnvironmentFile=/etc/environment -WorkingDirectory=/home/datadog -ExecStart=/bin/bash -c 'node index.js >> /home/datadog/app-std.out 2>&1 /dev/null + then + sudo yum groupinstall "Development Tools" -y + fi + sudo yum -y install patch + sudo sh python_install.sh rpm 2.7.18 + +weblog: + name: test-app-python-27 + excluded_os_branches: [amazon_linux2, rhel_7_amd64, redhat, ubuntu23] + install: + - os_type: linux + + copy_files: + - name: copy-service + local_path: utils/build/virtual_machine/weblogs/common/test-app.service + + - name: copy-service-run-script + local_path: utils/build/virtual_machine/weblogs/common/create_and_run_app_service.sh + + - name: copy-run-weblog-script + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-27/test-app-python_run.sh + + - name: copy-python-app + local_path: lib-injection/build/docker/python/dd-lib-python-init-test-django-27 + + remote-command: export PATH="/home/datadog/.pyenv/bin:$PATH" && eval "$(pyenv init -)" && sudo sh test-app-python_run.sh diff --git a/utils/build/virtual_machine/weblogs/python/provision_test-app-python-alpine-libgcc.yml b/utils/build/virtual_machine/weblogs/python/provision_test-app-python-alpine-libgcc.yml deleted file mode 100644 index 7822bbd7f00..00000000000 --- a/utils/build/virtual_machine/weblogs/python/provision_test-app-python-alpine-libgcc.yml +++ /dev/null @@ -1,17 +0,0 @@ -weblog: - name: test-app-python-alpine-libgcc - excluded_os_branches: [amazon_linux2_dotnet6, amazon_linux2023_amd64] - install: - - os_type: linux - copy_files: - - name: copy-run-weblog-script - local_path: utils/build/virtual_machine/weblogs/python/test-app-python-alpine/test-app-python_docker_compose_run.sh - - name: copy-docker-compose-file - local_path: utils/build/virtual_machine/weblogs/python/test-app-python-container/docker-compose.yml - - name: copy-python-app - local_path: lib-injection/build/docker/python/dd-lib-python-init-test-django - - name: copy-python-app-dockerfile - local_path: utils/build/virtual_machine/weblogs/python/test-app-python-alpine/Dockerfile.libgcc.template - remote_path: Dockerfile.template - - remote-command: sh test-app-python_docker_compose_run.sh \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/python/provision_test-app-python-alpine.yml b/utils/build/virtual_machine/weblogs/python/provision_test-app-python-alpine.yml index 2011a1c4a3c..ac69010109f 100644 --- a/utils/build/virtual_machine/weblogs/python/provision_test-app-python-alpine.yml +++ b/utils/build/virtual_machine/weblogs/python/provision_test-app-python-alpine.yml @@ -1,16 +1,17 @@ weblog: name: test-app-python-alpine - excluded_os_branches: [amazon_linux2_dotnet6, amazon_linux2023_amd64] + runtime_version: 3.12 install: - os_type: linux copy_files: - - name: copy-run-weblog-script - local_path: utils/build/virtual_machine/weblogs/python/test-app-python-alpine/test-app-python_docker_compose_run.sh + - name: copy-container-run-script + local_path: utils/build/virtual_machine/weblogs/common/create_and_run_app_container.sh - name: copy-docker-compose-file - local_path: utils/build/virtual_machine/weblogs/python/test-app-python-container/docker-compose.yml + local_path: utils/build/virtual_machine/weblogs/common/docker-compose.yml - name: copy-python-app local_path: lib-injection/build/docker/python/dd-lib-python-init-test-django - name: copy-python-app-dockerfile local_path: utils/build/virtual_machine/weblogs/python/test-app-python-alpine/Dockerfile.template + remote_path: Dockerfile.template - remote-command: sh test-app-python_docker_compose_run.sh \ No newline at end of file + remote-command: sh create_and_run_app_container.sh diff --git a/utils/build/virtual_machine/weblogs/python/provision_test-app-python-container.yml b/utils/build/virtual_machine/weblogs/python/provision_test-app-python-container.yml index de1806b4503..eb4f3a6bf84 100644 --- a/utils/build/virtual_machine/weblogs/python/provision_test-app-python-container.yml +++ b/utils/build/virtual_machine/weblogs/python/provision_test-app-python-container.yml @@ -1,16 +1,16 @@ weblog: name: test-app-python-container - excluded_os_branches: [amazon_linux2_dotnet6, amazon_linux2023_amd64] + runtime_version: 3.12 install: - os_type: linux copy_files: - - name: copy-run-weblog-script - local_path: utils/build/virtual_machine/weblogs/python/test-app-python-container/test-app-python_docker_compose_run.sh + - name: copy-container-run-script + local_path: utils/build/virtual_machine/weblogs/common/create_and_run_app_container.sh - name: copy-docker-compose-file - local_path: utils/build/virtual_machine/weblogs/python/test-app-python-container/docker-compose.yml + local_path: utils/build/virtual_machine/weblogs/common/docker-compose.yml - name: copy-python-app local_path: lib-injection/build/docker/python/dd-lib-python-init-test-django - name: copy-python-app-dockerfile local_path: utils/build/virtual_machine/weblogs/python/test-app-python-container/Dockerfile.template - remote-command: sh test-app-python_docker_compose_run.sh + remote-command: sh create_and_run_app_container.sh diff --git a/utils/build/virtual_machine/weblogs/python/provision_test-app-python-multialpine.yml b/utils/build/virtual_machine/weblogs/python/provision_test-app-python-multialpine.yml new file mode 100644 index 00000000000..f0194f71505 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/provision_test-app-python-multialpine.yml @@ -0,0 +1,27 @@ +weblog: + name: test-app-python-multialpine + nginx_config: utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/nginx.conf + install: + - os_type: linux + copy_files: + - name: copy-multicontainer-run-script + local_path: utils/build/virtual_machine/weblogs/common/create_and_run_app_multicontainer.sh + - name: copy-docker-compose-file + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/docker-compose.yml + - name: copy-python-app + local_path: lib-injection/build/docker/python/dd-lib-python-init-test-django + - name: copy-python3_12-app-dockerfile + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_12-alpine + - name: copy-python3_11-app-dockerfile + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_11-alpine + - name: copy-python3_10-app-dockerfile + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_10-alpine + - name: copy-python3_9-app-dockerfile + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_9-alpine + - name: copy-python3_7-app-dockerfile + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_7-alpine + - name: copy-reverseproxy-dockerfile + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.reverseproxy + - name: copy-reverseproxy-conf + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/nginx.conf + remote-command: sh create_and_run_app_multicontainer.sh diff --git a/utils/build/virtual_machine/weblogs/python/provision_test-app-python-multicontainer.yml b/utils/build/virtual_machine/weblogs/python/provision_test-app-python-multicontainer.yml new file mode 100644 index 00000000000..5e4ff942303 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/provision_test-app-python-multicontainer.yml @@ -0,0 +1,29 @@ +weblog: + name: test-app-python-multicontainer + nginx_config: utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/nginx.conf + install: + - os_type: linux + copy_files: + - name: copy-multicontainer-run-script + local_path: utils/build/virtual_machine/weblogs/common/create_and_run_app_multicontainer.sh + - name: copy-docker-compose-file + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/docker-compose.yml + - name: copy-python-app + local_path: lib-injection/build/docker/python/dd-lib-python-init-test-django + - name: copy-python3_12-app-dockerfile + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_12 + - name: copy-python3_11-app-dockerfile + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_11 + - name: copy-python3_10-app-dockerfile + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_10 + - name: copy-python3_9-app-dockerfile + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_9 + - name: copy-python3_8-app-dockerfile + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_8 + - name: copy-python3_7-app-dockerfile + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_7 + - name: copy-reverseproxy-dockerfile + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.reverseproxy + - name: copy-reverseproxy-conf + local_path: utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/nginx.conf + remote-command: sh create_and_run_app_multicontainer.sh diff --git a/utils/build/virtual_machine/weblogs/python/provision_test-app-python-unsupported-defaults.yml b/utils/build/virtual_machine/weblogs/python/provision_test-app-python-unsupported-defaults.yml new file mode 100644 index 00000000000..f55d05ff5bf --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/provision_test-app-python-unsupported-defaults.yml @@ -0,0 +1,66 @@ +lang_variant: + name: Python + version: default + cache: true + install: + + - os_type: linux + os_distro: rpm + os_branch: centos_7_amd64 + remote-command: | + sudo yum install -y python3 + #Remove the symlink to python2 + sudo unlink /usr/bin/python + sudo ln -s /usr/bin/python3 /usr/bin/python + #Some fixes for the yum package manager (no compatible with python3) + sudo sed -i '1s|.*|#!/usr/bin/python2|' /usr/bin/yum + sudo sed -i '1s|.*|#!/usr/bin/python2|' /usr/libexec/urlgrabber-ext-down + + - os_type: linux + os_distro: rpm + os_branch: centos_8_amd64 + remote-command: | + sudo dnf install -y python3 + sudo ln -s /usr/bin/python3 /usr/bin/python + + - os_type: linux + os_distro: rpm + os_branch: redhat + remote-command: | + sudo dnf install -y python3 + sudo ln -s /usr/bin/python3 /usr/bin/python || true + + - os_type: linux + os_distro: rpm + os_branch: rhel_7_amd64 + remote-command: | + sudo yum install -y python3 + #Remove the symlink to python2 + sudo unlink /usr/bin/python + sudo ln -s /usr/bin/python3 /usr/bin/python + #Some fixes for the yum package manager (no compatible with python3) + sudo sed -i '1s|.*|#!/usr/bin/python2|' /usr/bin/yum + sudo sed -i '1s|.*|#!/usr/bin/python2|' /usr/libexec/urlgrabber-ext-down + + + +weblog: + name: test-app-python-unsupported-defaults + exact_os_branches: [RedHat_8_6_arm64, RedHat_8_6_amd64, centos_7_amd64, centos_8_amd64, rhel_7_amd64] + install: + - os_type: linux + + copy_files: + - name: copy-service + local_path: utils/build/virtual_machine/weblogs/common/test-app.service + + - name: copy-service-run-script + local_path: utils/build/virtual_machine/weblogs/common/create_and_run_app_service.sh + + - name: copy-run-weblog-script + local_path: utils/build/virtual_machine/weblogs/python/test-app-python/test-app-python_run.sh + + - name: copy-python-app + local_path: lib-injection/build/docker/python/dd-lib-python-init-test-django + + remote-command: export PATH="/home/datadog/.pyenv/bin:$PATH" && eval "$(pyenv init -)" && sudo sh test-app-python_run.sh diff --git a/utils/build/virtual_machine/weblogs/python/provision_test-app-python.yml b/utils/build/virtual_machine/weblogs/python/provision_test-app-python.yml index 3bcc8cdcf5d..367f65bad55 100644 --- a/utils/build/virtual_machine/weblogs/python/provision_test-app-python.yml +++ b/utils/build/virtual_machine/weblogs/python/provision_test-app-python.yml @@ -1,31 +1,48 @@ lang_variant: - name: Python_3.8.15 - version: 3.8.15 + name: Python + version: default cache: true install: - os_type: linux os_distro: deb - copy_files: - - name: copy-auto-install-script - local_path: utils/build/virtual_machine/weblogs/python/test-app-python/python_install.sh - remote-command: sudo apt-get -y update && sudo sh python_install.sh deb 3.8.15 + remote-command: | + sudo apt-get update + sudo apt install -y python-is-python3 + sudo apt install -y python3-pip + sudo apt install -y python3-django || true - os_type: linux os_distro: rpm - copy_files: - - name: copy-auto-install-script - local_path: utils/build/virtual_machine/weblogs/python/test-app-python/python_install.sh - remote-command: sudo sh python_install.sh rpm 3.8.15 + os_branch: redhat + remote-command: | + #Redhat 9 is going to install python 3.9. + sudo dnf install -y python3 + sudo ln -s /usr/bin/python3 /usr/bin/python || true + sudo dnf install -y python-pip + + - os_type: linux + os_distro: rpm + remote-command: | + #works for: amazon_linux2022, amazon_linux2023_arm64 and amazon_linux2023_amd64 + sudo ln -s /usr/bin/python3 /usr/bin/python && sudo dnf install -y python-pip weblog: name: test-app-python - excluded_os_branches: [amazon_linux2_dotnet6] + #AL2 uses the yum package manager that has a hard dependency on Python 2.7 + #Centos 7 is going to install python 3.6. Not supported. + #Centos 8 is going to install python 3.6. Not supported. + #Rhel 7 is going to install python 3.6. Not supported. + excluded_os_branches: [ amazon_linux2, centos_7_amd64, centos_8_amd64, rhel_7_amd64] + excluded_os_names: [RedHat_8_6_arm64, RedHat_8_6_amd64] install: - os_type: linux copy_files: - name: copy-service - local_path: utils/build/virtual_machine/weblogs/python/test-app-python/test-app.service + local_path: utils/build/virtual_machine/weblogs/common/test-app.service + + - name: copy-service-run-script + local_path: utils/build/virtual_machine/weblogs/common/create_and_run_app_service.sh - name: copy-run-weblog-script local_path: utils/build/virtual_machine/weblogs/python/test-app-python/test-app-python_run.sh @@ -33,4 +50,4 @@ weblog: - name: copy-python-app local_path: lib-injection/build/docker/python/dd-lib-python-init-test-django - remote-command: export PATH="/home/datadog/.pyenv/bin:$PATH" && eval "$(pyenv init -)" && sudo sh test-app-python_run.sh \ No newline at end of file + remote-command: export PATH="/home/datadog/.pyenv/bin:$PATH" && eval "$(pyenv init -)" && sudo sh test-app-python_run.sh diff --git a/utils/build/virtual_machine/weblogs/python/provision_test-shell-script.yml b/utils/build/virtual_machine/weblogs/python/provision_test-shell-script.yml deleted file mode 100644 index b62ab041f76..00000000000 --- a/utils/build/virtual_machine/weblogs/python/provision_test-shell-script.yml +++ /dev/null @@ -1,31 +0,0 @@ -lang_variant: - name: Python_3.8.15 - version: 3.8.15 - cache: true - install: - - os_type: linux - os_distro: deb - copy_files: - - name: copy-auto-install-script - local_path: utils/build/virtual_machine/weblogs/python/test-app-python/python_install.sh - remote-command: sudo apt-get -y update && sudo sh python_install.sh deb 3.8.15 - - - os_type: linux - os_distro: rpm - copy_files: - - name: copy-auto-install-script - local_path: utils/build/virtual_machine/weblogs/python/test-app-python/python_install.sh - remote-command: sudo sh python_install.sh rpm 3.8.15 - - -weblog: - name: test-shell-script - excluded_os_branches: [amazon_linux2_dotnet6, amazon_linux2023_amd64] - install: - - os_type: linux - remote-command: | - sudo mkdir /opt/datadog/logs_injection && sudo chmod -R 777 /opt/datadog/logs_injection - sudo touch /opt/datadog/logs_injection/host_injection.log && sudo chmod 777 /opt/datadog/logs_injection/host_injection.log - sudo sh -c 'echo "DD_APM_INSTRUMENTATION_DEBUG=TRUE" >> /etc/environment' - sudo sh -c 'echo "DD_APM_INSTRUMENTATION_OUTPUT_PATHS=/opt/datadog/logs_injection/host_injection.log" >> /etc/environment' - source /etc/environment diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-27/python_install.sh b/utils/build/virtual_machine/weblogs/python/test-app-python-27/python_install.sh new file mode 100755 index 00000000000..ac43611315a --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-27/python_install.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +DISTRO=$1 +PY_VERSION=$2 + +#Workaround: if python install pyenv +if [ "$DISTRO" = "deb" ]; then + #Install pyenv + packages_install="make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev git curl llvm libncursesw5-dev xz-utils tk-dev tzdata libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev" + # shellcheck disable=SC2086 + sudo apt-get install -y $packages_install || ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends $packages_install + export PYENV_ROOT="/home/datadog/.pyenv" + sudo curl https://pyenv.run | bash + export PATH="$PYENV_ROOT/bin:$PATH" + eval "$(pyenv init -)" + else + #Install pyenv + sudo yum install -y gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel git + git clone https://github.com/pyenv/pyenv.git /home/datadog/.pyenv + export PYENV_ROOT="/home/datadog/.pyenv" + export PATH="$PYENV_ROOT/bin:$PATH" + eval "$(pyenv init -)" + fi + + +export PATH="/home/datadog/.pyenv/bin:$PATH" && eval "$(pyenv init -)" && pyenv install "$PY_VERSION" && pyenv global "$PY_VERSION" diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-27/test-app-python_run.sh b/utils/build/virtual_machine/weblogs/python/test-app-python-27/test-app-python_run.sh new file mode 100755 index 00000000000..9dc881ae532 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-27/test-app-python_run.sh @@ -0,0 +1,16 @@ +#!/bin/bash +echo "START python APP" + +set -e + +# shellcheck disable=SC2035 +sudo chmod -R 755 * + +sudo cp django_app.py /home/datadog/ +sudo /home/datadog/.pyenv/shims/pip install django +echo "Testing weblog with python version:" +sudo /home/datadog/.pyenv/shims/python --version +./create_and_run_app_service.sh "/home/datadog/.pyenv/shims/python -m django runserver 0.0.0.0:5985" "PYTHONPATH=/home/datadog/:$PYTHONPATH PYTHONUNBUFFERED=1 DJANGO_SETTINGS_MODULE=django_app" +echo "RUN AFTER THE SERVICE" +cat test-app.service +echo "RUN python DONE" diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-alpine/Dockerfile.libgcc.template b/utils/build/virtual_machine/weblogs/python/test-app-python-alpine/Dockerfile.libgcc.template deleted file mode 100644 index a363a4f5764..00000000000 --- a/utils/build/virtual_machine/weblogs/python/test-app-python-alpine/Dockerfile.libgcc.template +++ /dev/null @@ -1,12 +0,0 @@ -FROM public.ecr.aws/docker/library/python:3-alpine -# Install python/pip -ENV PYTHONUNBUFFERED=1 -RUN apk add libgcc -RUN pip3 install --no-cache --upgrade pip setuptools - -ENV DJANGO_SETTINGS_MODULE django_app -WORKDIR /src -ADD . /src -RUN pip3 install django -EXPOSE 18080 -CMD python3 -m django runserver 0.0.0.0:18080 \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-alpine/Dockerfile.template b/utils/build/virtual_machine/weblogs/python/test-app-python-alpine/Dockerfile.template index fe7520d6dfd..c2b90ba1b94 100644 --- a/utils/build/virtual_machine/weblogs/python/test-app-python-alpine/Dockerfile.template +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-alpine/Dockerfile.template @@ -1,7 +1,6 @@ -FROM public.ecr.aws/docker/library/python:3-alpine +FROM public.ecr.aws/docker/library/python:3.12-alpine # Install python/pip ENV PYTHONUNBUFFERED=1 - RUN pip3 install --no-cache --upgrade pip setuptools ENV DJANGO_SETTINGS_MODULE django_app @@ -9,4 +8,4 @@ WORKDIR /src ADD . /src RUN pip3 install django EXPOSE 18080 -CMD python3 -m django runserver 0.0.0.0:18080 \ No newline at end of file +CMD python3 -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-alpine/docker-compose.yml b/utils/build/virtual_machine/weblogs/python/test-app-python-alpine/docker-compose.yml deleted file mode 100644 index ad867ad0534..00000000000 --- a/utils/build/virtual_machine/weblogs/python/test-app-python-alpine/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: '3' -services: - test-app-python: - container_name: test-app-python - image: system-tests/local:latest - ports: - - 5985:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-alpine/test-app-python_docker_compose_run.sh b/utils/build/virtual_machine/weblogs/python/test-app-python-alpine/test-app-python_docker_compose_run.sh deleted file mode 100755 index ccf42107c53..00000000000 --- a/utils/build/virtual_machine/weblogs/python/test-app-python-alpine/test-app-python_docker_compose_run.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC2015 - -set -e - -# shellcheck disable=SC2035 -sudo chmod -R 755 * - -rm -rf Dockerfile || true -cp Dockerfile.template Dockerfile || true - -sudo docker build --no-cache -t system-tests/local . -if [ -f docker-compose-agent-prod.yml ]; then - # Agent may be installed in a different way - sudo -E docker-compose -f docker-compose-agent-prod.yml up -d --remove-orphans datadog - sleep 30 -fi -sudo -E docker-compose -f docker-compose.yml up -d test-app-python - -echo "**************** RUNNING DOCKER SERVICES *****************" -sudo docker-compose ps -if [ -f docker-compose-agent-prod.yml ]; then - echo "**************** DATADOG AGENT OUTPUT ********************" - sudo docker-compose -f docker-compose-agent-prod.yml logs datadog -fi -echo "**************** WEBLOG APP OUTPUT********************" -sudo docker-compose logs -echo "RUN DONE" diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-container/Dockerfile.template b/utils/build/virtual_machine/weblogs/python/test-app-python-container/Dockerfile.template index a432bf64417..caf5846d295 100644 --- a/utils/build/virtual_machine/weblogs/python/test-app-python-container/Dockerfile.template +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-container/Dockerfile.template @@ -1,4 +1,4 @@ -FROM public.ecr.aws/docker/library/python:3 +FROM public.ecr.aws/docker/library/python:3.12 ENV PYTHONUNBUFFERED 1 ENV DJANGO_SETTINGS_MODULE django_app @@ -6,4 +6,4 @@ WORKDIR /src ADD . /src RUN pip install django EXPOSE 18080 -CMD python -m django runserver 0.0.0.0:18080 +ENTRYPOINT ["python", "-m", "django", "runserver", "0.0.0.0:18080"] \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-container/docker-compose.yml b/utils/build/virtual_machine/weblogs/python/test-app-python-container/docker-compose.yml deleted file mode 100644 index ad867ad0534..00000000000 --- a/utils/build/virtual_machine/weblogs/python/test-app-python-container/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: '3' -services: - test-app-python: - container_name: test-app-python - image: system-tests/local:latest - ports: - - 5985:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-container/test-app-python_docker_compose_run.sh b/utils/build/virtual_machine/weblogs/python/test-app-python-container/test-app-python_docker_compose_run.sh deleted file mode 100755 index ccf42107c53..00000000000 --- a/utils/build/virtual_machine/weblogs/python/test-app-python-container/test-app-python_docker_compose_run.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC2015 - -set -e - -# shellcheck disable=SC2035 -sudo chmod -R 755 * - -rm -rf Dockerfile || true -cp Dockerfile.template Dockerfile || true - -sudo docker build --no-cache -t system-tests/local . -if [ -f docker-compose-agent-prod.yml ]; then - # Agent may be installed in a different way - sudo -E docker-compose -f docker-compose-agent-prod.yml up -d --remove-orphans datadog - sleep 30 -fi -sudo -E docker-compose -f docker-compose.yml up -d test-app-python - -echo "**************** RUNNING DOCKER SERVICES *****************" -sudo docker-compose ps -if [ -f docker-compose-agent-prod.yml ]; then - echo "**************** DATADOG AGENT OUTPUT ********************" - sudo docker-compose -f docker-compose-agent-prod.yml logs datadog -fi -echo "**************** WEBLOG APP OUTPUT********************" -sudo docker-compose logs -echo "RUN DONE" diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_10-alpine b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_10-alpine new file mode 100644 index 00000000000..5ff08186144 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_10-alpine @@ -0,0 +1,10 @@ +FROM public.ecr.aws/docker/library/python:3.10-alpine + +RUN apk add --no-cache curl +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_11-alpine b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_11-alpine new file mode 100644 index 00000000000..650807023d7 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_11-alpine @@ -0,0 +1,10 @@ +FROM public.ecr.aws/docker/library/python:3.11-alpine + +RUN apk add --no-cache curl +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_12-alpine b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_12-alpine new file mode 100644 index 00000000000..ebaf365f305 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_12-alpine @@ -0,0 +1,10 @@ +FROM public.ecr.aws/docker/library/python:3.12-alpine + +RUN apk add --no-cache curl +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_7-alpine b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_7-alpine new file mode 100644 index 00000000000..993baac6931 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_7-alpine @@ -0,0 +1,10 @@ +FROM public.ecr.aws/docker/library/python:3.7-alpine + +RUN apk add --no-cache curl +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_8-alpine b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_8-alpine new file mode 100644 index 00000000000..49b9eff10b1 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_8-alpine @@ -0,0 +1,10 @@ +FROM public.ecr.aws/docker/library/python:3.8-alpine + +RUN apk add --no-cache curl +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_9-alpine b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_9-alpine new file mode 100644 index 00000000000..d1861e02aff --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.python_3_9-alpine @@ -0,0 +1,10 @@ +FROM public.ecr.aws/docker/library/python:3.9-alpine + +RUN apk add --no-cache curl +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.reverseproxy b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.reverseproxy new file mode 100644 index 00000000000..82cdb622233 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/Dockerfile.reverseproxy @@ -0,0 +1,3 @@ +FROM public.ecr.aws/nginx/nginx:stable-perl + +COPY nginx.conf /etc/nginx/nginx.conf \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/docker-compose.yml b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/docker-compose.yml new file mode 100644 index 00000000000..d739661abdb --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/docker-compose.yml @@ -0,0 +1,63 @@ +version: '2' + +services: + reverseproxy: + image: reverseproxy:latest + ports: + - 5985:8080 + restart: always + build: + context: . + dockerfile: Dockerfile.reverseproxy + healthcheck: + test: "curl -f http://localhost:8080" + + python_3_12: + env_file: "scenario_app.env" + image: system-tests/python_3_12:latest + restart: always + build: + context: . + dockerfile: Dockerfile.python_3_12-alpine + healthcheck: + test: "curl -f http://localhost:18080" + + python_3_11: + env_file: "scenario_app.env" + image: system-tests/python_3_11:latest + restart: always + build: + context: . + dockerfile: Dockerfile.python_3_11-alpine + healthcheck: + test: "curl -f http://localhost:18080" + + python_3_10: + env_file: "scenario_app.env" + image: system-tests/python_3_10:latest + restart: always + build: + context: . + dockerfile: Dockerfile.python_3_10-alpine + healthcheck: + test: "curl -f http://localhost:18080" + + python_3_9: + env_file: "scenario_app.env" + image: system-tests/python_3_9:latest + restart: always + build: + context: . + dockerfile: Dockerfile.python_3_9-alpine + healthcheck: + test: "curl -f http://localhost:18080" + + python_3_7: + env_file: "scenario_app.env" + image: system-tests/python_3_7:latest + restart: always + build: + context: . + dockerfile: Dockerfile.python_3_7-alpine + healthcheck: + test: "curl -f http://localhost:18080" \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/nginx.conf b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/nginx.conf new file mode 100644 index 00000000000..c610fd94033 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multialpine/nginx.conf @@ -0,0 +1,82 @@ +worker_processes 1; + +events { worker_connections 1024; } + + +http { + + log_format compression '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $upstream_addr ' + '"$http_referer" "$http_user_agent" "$gzip_ratio"'; + + upstream python_3_12_app { + server python_3_12:18080; + } + upstream python_3_11_app { + server python_3_11:18080; + } + upstream python_3_10_app { + server python_3_10:18080; + } + upstream python_3_9_app { + server python_3_9:18080; + } + upstream python_3_7_app { + server python_3_7:18080; + } + server { + listen 8080; + access_log /var/log/nginx/access.log compression; + + location / { + default_type application/json; + return 200 "{ + 'app_type':'multicontainer', + 'apps':[{ + 'runtime':'3.12', + 'type':'alpine', + 'url':'/python_3_12/' + },{ + 'runtime':'3.11', + 'type':'alpine', + 'url':'/python_3_11/' + },{ + 'runtime':'3.10', + 'type':'alpine', + 'url':'/python_3_10/' + },{ + 'runtime':'3.9', + 'type':'alpine', + 'url':'/python_3_9/' + },{ + 'runtime':'3.7', + 'type':'alpine', + 'url':'/python_3_7/' + } + + ] + }"; + } + + location /python_3_12/ { + proxy_pass http://python_3_12_app/; + proxy_redirect off; + } + location /python_3_11/ { + proxy_pass http://python_3_11_app/; + proxy_redirect off; + } + location /python_3_10/ { + proxy_pass http://python_3_10_app/; + proxy_redirect off; + } + location /python_3_9/ { + proxy_pass http://python_3_9_app/; + proxy_redirect off; + } + location /python_3_7/ { + proxy_pass http://python_3_7_app/; + proxy_redirect off; + } + } +} \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_10 b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_10 new file mode 100644 index 00000000000..2b1b9f292f4 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_10 @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/python:3.10 + +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_11 b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_11 new file mode 100644 index 00000000000..80c8105f860 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_11 @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/python:3.11 + +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_12 b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_12 new file mode 100644 index 00000000000..e53d686eabe --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_12 @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/python:3.12 + +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_7 b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_7 new file mode 100644 index 00000000000..f3bd08a7c0b --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_7 @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/python:3.7 + +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_8 b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_8 new file mode 100644 index 00000000000..c372114a876 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_8 @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/python:3.8 + +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_9 b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_9 new file mode 100644 index 00000000000..1bb3bff87fe --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.python_3_9 @@ -0,0 +1,9 @@ +FROM public.ecr.aws/docker/library/python:3.9 + +ENV PYTHONUNBUFFERED 1 +ENV DJANGO_SETTINGS_MODULE django_app +WORKDIR /src +ADD . /src +RUN pip install django +EXPOSE 18080 +CMD python -m django runserver 0.0.0.0:18080 diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.reverseproxy b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.reverseproxy new file mode 100644 index 00000000000..82cdb622233 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/Dockerfile.reverseproxy @@ -0,0 +1,3 @@ +FROM public.ecr.aws/nginx/nginx:stable-perl + +COPY nginx.conf /etc/nginx/nginx.conf \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/docker-compose.yml b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/docker-compose.yml new file mode 100644 index 00000000000..50c3b82ccbc --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/docker-compose.yml @@ -0,0 +1,73 @@ +version: '2' + +services: + reverseproxy: + image: reverseproxy:latest + ports: + - 5985:8080 + restart: always + build: + context: . + dockerfile: Dockerfile.reverseproxy + healthcheck: + test: "curl -f http://localhost:8080" + + python_3_12: + env_file: "scenario_app.env" + image: system-tests/python_3_12:latest + restart: always + build: + context: . + dockerfile: Dockerfile.python_3_12 + healthcheck: + test: "curl -f http://localhost:18080" + + python_3_11: + env_file: "scenario_app.env" + image: system-tests/python_3_11:latest + restart: always + build: + context: . + dockerfile: Dockerfile.python_3_11 + healthcheck: + test: "curl -f http://localhost:18080" + + python_3_10: + env_file: "scenario_app.env" + image: system-tests/python_3_10:latest + restart: always + build: + context: . + dockerfile: Dockerfile.python_3_10 + healthcheck: + test: "curl -f http://localhost:18080" + + python_3_9: + env_file: "scenario_app.env" + image: system-tests/python_3_9:latest + restart: always + build: + context: . + dockerfile: Dockerfile.python_3_9 + healthcheck: + test: "curl -f http://localhost:18080" + + python_3_8: + env_file: "scenario_app.env" + image: system-tests/python_3_8:latest + restart: always + build: + context: . + dockerfile: Dockerfile.python_3_8 + healthcheck: + test: "curl -f http://localhost:18080" + + python_3_7: + env_file: "scenario_app.env" + image: system-tests/python_3_7:latest + restart: always + build: + context: . + dockerfile: Dockerfile.python_3_7 + healthcheck: + test: "curl -f http://localhost:18080" \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/nginx.conf b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/nginx.conf new file mode 100644 index 00000000000..7aa9c856d54 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/python/test-app-python-multicontainer/nginx.conf @@ -0,0 +1,93 @@ +worker_processes 1; + +events { worker_connections 1024; } + + +http { + + log_format compression '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $upstream_addr ' + '"$http_referer" "$http_user_agent" "$gzip_ratio"'; + + upstream python_3_12_app { + server python_3_12:18080; + } + upstream python_3_11_app { + server python_3_11:18080; + } + upstream python_3_10_app { + server python_3_10:18080; + } + upstream python_3_9_app { + server python_3_9:18080; + } + upstream python_3_8_app { + server python_3_8:18080; + } + upstream python_3_7_app { + server python_3_7:18080; + } + server { + listen 8080; + access_log /var/log/nginx/access.log compression; + + location / { + default_type application/json; + return 200 "{ + 'app_type':'multicontainer', + 'apps':[{ + 'runtime':'3.12', + 'type':'container', + 'url':'/python_3_12/' + },{ + 'runtime':'3.11', + 'type':'container', + 'url':'/python_3_11/' + },{ + 'runtime':'3.10', + 'type':'container', + 'url':'/python_3_10/' + },{ + 'runtime':'3.9', + 'type':'container', + 'url':'/python_3_9/' + },{ + 'runtime':'3.8', + 'type':'container', + 'url':'/python_3_8/' + },{ + 'runtime':'3.7', + 'type':'container', + 'url':'/python_3_7/' + } + + ] + }"; + } + + location /python_3_12/ { + proxy_pass http://python_3_12_app/; + proxy_redirect off; + } + location /python_3_11/ { + proxy_pass http://python_3_11_app/; + proxy_redirect off; + } + location /python_3_10/ { + proxy_pass http://python_3_10_app/; + proxy_redirect off; + } + location /python_3_9/ { + proxy_pass http://python_3_9_app/; + proxy_redirect off; + } + location /python_3_8/ { + proxy_pass http://python_3_8_app/; + proxy_redirect off; + } + location /python_3_7/ { + proxy_pass http://python_3_7_app/; + proxy_redirect off; + } + } +} \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python/python_install.sh b/utils/build/virtual_machine/weblogs/python/test-app-python/python_install.sh index 2dad2bbf7b4..ac43611315a 100755 --- a/utils/build/virtual_machine/weblogs/python/test-app-python/python_install.sh +++ b/utils/build/virtual_machine/weblogs/python/test-app-python/python_install.sh @@ -8,7 +8,7 @@ if [ "$DISTRO" = "deb" ]; then #Install pyenv packages_install="make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev git curl llvm libncursesw5-dev xz-utils tk-dev tzdata libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev" # shellcheck disable=SC2086 - sudo apt-get install -y $packages_install || ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "$packages_install" + sudo apt-get install -y $packages_install || ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends $packages_install export PYENV_ROOT="/home/datadog/.pyenv" sudo curl https://pyenv.run | bash export PATH="$PYENV_ROOT/bin:$PATH" @@ -23,4 +23,4 @@ if [ "$DISTRO" = "deb" ]; then fi -export PATH="/home/datadog/.pyenv/bin:$PATH" && eval "$(pyenv init -)" && pyenv install "$PY_VERSION" && pyenv global "$PY_VERSION" \ No newline at end of file +export PATH="/home/datadog/.pyenv/bin:$PATH" && eval "$(pyenv init -)" && pyenv install "$PY_VERSION" && pyenv global "$PY_VERSION" diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python/test-app-python_run.sh b/utils/build/virtual_machine/weblogs/python/test-app-python/test-app-python_run.sh index cd5cdd3d74f..5943ed42209 100755 --- a/utils/build/virtual_machine/weblogs/python/test-app-python/test-app-python_run.sh +++ b/utils/build/virtual_machine/weblogs/python/test-app-python/test-app-python_run.sh @@ -1,5 +1,5 @@ #!/bin/bash -echo "START RUN APP" +echo "START python APP" set -e @@ -7,14 +7,6 @@ set -e sudo chmod -R 755 * sudo cp django_app.py /home/datadog/ -sudo /home/datadog/.pyenv/shims/pip3 install django -echo "Testing weblog with python version:" -sudo /home/datadog/.pyenv/shims/python --version -sudo cp test-app.service /etc/systemd/system/test-app.service -sudo systemctl daemon-reload -sudo systemctl enable test-app.service -sudo systemctl start test-app.service -sudo systemctl status test-app.service -sleep 5 -cat /home/datadog/app-std.out -echo "RUN DONE" \ No newline at end of file +sudo pip3 install django || true +./create_and_run_app_service.sh "python -m django runserver 0.0.0.0:5985" "PYTHONUNBUFFERED=1 DJANGO_SETTINGS_MODULE=django_app" +echo "RUN python DONE" \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/python/test-app-python/test-app.service b/utils/build/virtual_machine/weblogs/python/test-app-python/test-app.service deleted file mode 100644 index 60bb529af07..00000000000 --- a/utils/build/virtual_machine/weblogs/python/test-app-python/test-app.service +++ /dev/null @@ -1,20 +0,0 @@ -[Unit] -Description=Python Weblog App Service -After=syslog.target network.target - -[Service] -SuccessExitStatus=143 - -User=datadog - -Type=simple - -Environment=DD_APM_INSTRUMENTATION_DEBUG=TRUE -Environment=PYTHONUNBUFFERED=1 -Environment=DJANGO_SETTINGS_MODULE=django_app -WorkingDirectory=/home/datadog -ExecStart=/bin/bash -c '/home/datadog/.pyenv/shims/python -m django runserver 0.0.0.0:5985 >> /home/datadog/app-std.out 2>&1 2.3.26' + sudo apt update + sudo apt install -y git curl libssl-dev libreadline-dev zlib1g-dev autoconf bison build-essential libyaml-dev libreadline-dev libncurses5-dev libffi-dev libgdbm-dev + curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash + export PATH=~/.rbenv/bin/:~/.rbenv/shims:$PATH + curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-doctor | bash + rbenv install 3.0.2 --verbose + rbenv global 3.0.2 + DD_INSTRUMENT_SERVICE_WITH_APM=false gem install bundler -v '~> 2.3.27' + - os_type: linux os_distro: rpm remote-command: | - sudo yum install -y gcc libyaml-devel - sudo amazon-linux-extras install -y ruby3.0 - sudo yum install -y ruby-devel - sudo yum groupinstall -y "Development Tools" - sudo DD_INSTRUMENT_SERVICE_WITH_APM=false gem install rails - sudo DD_INSTRUMENT_SERVICE_WITH_APM=false gem install bundler -v '~> 2.3.26' + sudo yum remove rubygem-bundler || true + sudo yum install -y gcc libyaml-devel curl + sudo yum install openssl-devel -y + if ! command -v amazon-linux-extras 2>&1 >/dev/null + then + echo "Installing perl and deps" + sudo dnf install -y gpg gcc gcc-c++ make rust patch make bzip2 libffi-devel readline-devel zlib-devel ncurses-devel + sudo dnf -y install gdbm-devel || true + sudo dnf -y install perl + fi + curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash + export PATH=~/.rbenv/bin/:~/.rbenv/shims:$PATH + curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-doctor | bash + rbenv install 3.0.2 --verbose + rbenv global 3.0.2 + DD_INSTRUMENT_SERVICE_WITH_APM=false gem install bundler -v '~> 2.3.27' + weblog: name: test-app-ruby - excluded_os_branches: [amazon_linux2_dotnet6, ubuntu18_amd64, amazon_linux2_amd64, centos_7_amd64] + # fedora are excluded because they do not provide the right Ruby versions + # TODO oracle_linux and alma_linux. Failed when we run the app. Related with how we install Ruby + #Ubuntu_18_amd64, ubuntu 20: installation fails + #rhel_7_amd64 skipping (instrumentation) due to ignore rules for language ruby: Unsupported host architecture + excluded_os_branches: [ubuntu18_amd64,ubuntu20_amd64, ubuntu20_arm64, oracle_linux, alma_linux, fedora, debian, rhel_7_amd64] + excluded_os_names: [RedHat_9_0_amd64, RedHat_9_0_arm64] install: - os_type: linux copy_files: - name: copy-ruby-app - local_path: lib-injection/build/docker/ruby/lib_injection_rails_app + local_path: lib-injection/build/docker/ruby/lib_injection_rails_app - name: copy-service - local_path: utils/build/virtual_machine/weblogs/ruby/test-app-ruby/test-app.service + local_path: utils/build/virtual_machine/weblogs/ruby/test-app.service + + - name: copy-service-run-script + local_path: utils/build/virtual_machine/weblogs/common/create_and_run_app_service.sh - name: copy-run-weblog-script-ruby local_path: utils/build/virtual_machine/weblogs/ruby/test-app-ruby/test-app-ruby_run.sh - remote-command: sh test-app-ruby_run.sh \ No newline at end of file + remote-command: sh test-app-ruby_run.sh diff --git a/utils/build/virtual_machine/weblogs/ruby/provision_test-shell-script.yml b/utils/build/virtual_machine/weblogs/ruby/provision_test-shell-script.yml deleted file mode 100644 index 5e12fdeb57c..00000000000 --- a/utils/build/virtual_machine/weblogs/ruby/provision_test-shell-script.yml +++ /dev/null @@ -1,34 +0,0 @@ -lang_variant: - name: Ruby_3_0_2 - version: 3.0.2 - cache: true - install: - - os_type: linux - os_distro: deb - remote-command: | - sudo apt-get -y update - sudo DEBIAN_FRONTEND=noninteractive apt-get -y install git-core zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev software-properties-common libffi-dev nodejs yarn - sudo DEBIAN_FRONTEND=noninteractive apt-get -y install rbenv ruby-build ruby-dev - sudo DD_INSTRUMENT_SERVICE_WITH_APM=false gem install rails - sudo DD_INSTRUMENT_SERVICE_WITH_APM=false gem install bundler -v '~> 2.3.26' - - os_type: linux - os_distro: rpm - remote-command: | - sudo yum install -y gcc - sudo amazon-linux-extras install -y ruby3.0 - sudo yum install -y ruby-devel - sudo yum groupinstall -y "Development Tools" - sudo DD_INSTRUMENT_SERVICE_WITH_APM=false gem install rails - sudo DD_INSTRUMENT_SERVICE_WITH_APM=false gem install bundler -v '~> 2.3.26' - -weblog: - name: test-shell-script - excluded_os_branches: [amazon_linux2_dotnet6, amazon_linux2023_amd64, centos_7_amd64] - install: - - os_type: linux - remote-command: | - sudo mkdir /opt/datadog/logs_injection && sudo chmod -R 777 /opt/datadog/logs_injection - sudo touch /opt/datadog/logs_injection/host_injection.log && sudo chmod 777 /opt/datadog/logs_injection/host_injection.log - sudo sh -c 'echo "DD_APM_INSTRUMENTATION_DEBUG=TRUE" >> /etc/environment' - sudo sh -c 'echo "DD_APM_INSTRUMENTATION_OUTPUT_PATHS=/opt/datadog/logs_injection/host_injection.log" >> /etc/environment' - source /etc/environment diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-container/Dockerfile.template b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-container/Dockerfile.template index 894fe8130d6..28b23a1c55b 100644 --- a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-container/Dockerfile.template +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-container/Dockerfile.template @@ -45,7 +45,6 @@ COPY lib_injection_rails_app /app # Install gems RUN bundle install -# Set entrypoint -ENTRYPOINT ["/bin/bash", "-c"] +ENV DD_CRASHTRACKING_ENABLED true -CMD ["bin/rails server -b 0.0.0.0 -p 18080"] +ENTRYPOINT ["bin/rails", "server", "-b", "0.0.0.0", "-p", "18080"] diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-container/docker-compose.yml b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-container/docker-compose.yml deleted file mode 100644 index 5b6fc76af08..00000000000 --- a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-container/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: '3' -services: - test-app-ruby: - container_name: test-app-ruby - image: system-tests/local:latest - ports: - - 5985:18080 diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-container/test-app-ruby_docker_compose_run.sh b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-container/test-app-ruby_docker_compose_run.sh deleted file mode 100755 index 3eab838f066..00000000000 --- a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-container/test-app-ruby_docker_compose_run.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC2015 - -set -e - -# shellcheck disable=SC2035 -sudo chmod -R 755 * - -rm -rf Dockerfile || true -cp Dockerfile.template Dockerfile || true - -sudo docker build --no-cache -t system-tests/local . -if [ -f docker-compose-agent-prod.yml ]; then - # Agent may be installed in a different way - sudo -E docker-compose -f docker-compose-agent-prod.yml up -d --remove-orphans datadog - sleep 30 -fi -sudo -E docker-compose -f docker-compose.yml up -d test-app-ruby - -echo "**************** RUNNING DOCKER SERVICES *****************" -sudo docker-compose ps -if [ -f docker-compose-agent-prod.yml ]; then - echo "**************** DATADOG AGENT OUTPUT ********************" - sudo docker-compose -f docker-compose-agent-prod.yml logs datadog -fi -echo "**************** WEBLOG APP OUTPUT********************" -sudo docker-compose logs -echo "RUN DONE" diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.reverseproxy b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.reverseproxy new file mode 100644 index 00000000000..82cdb622233 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.reverseproxy @@ -0,0 +1,3 @@ +FROM public.ecr.aws/nginx/nginx:stable-perl + +COPY nginx.conf /etc/nginx/nginx.conf \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.ruby_2_7-alpine b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.ruby_2_7-alpine new file mode 100644 index 00000000000..24a5927f11b --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.ruby_2_7-alpine @@ -0,0 +1,27 @@ +FROM public.ecr.aws/docker/library/ruby:2.7-alpine + +ENV DEBIAN_FRONTEND=noninteractive + +# Set timezone to UTC by default +RUN ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime + +# Upgrade RubyGems and Bundler +RUN gem update --system 3.4.1 +RUN gem install bundler -v '~> 2.3.26' +RUN mkdir -p "$GEM_HOME" && chmod -R 777 "$GEM_HOME" +ENV BUNDLE_SILENCE_ROOT_WARNING 1 + +# Setup directory +RUN mkdir /app +WORKDIR /app + +# Add files +COPY lib_injection_rails_app /app + +# Install gems +RUN bundle install + +# Set entrypoint +ENTRYPOINT ["/bin/bash", "-c"] + +CMD ["bin/rails server -b 0.0.0.0 -p 18080"] diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.ruby_3_0-alpine b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.ruby_3_0-alpine new file mode 100644 index 00000000000..e159f60fb17 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.ruby_3_0-alpine @@ -0,0 +1,27 @@ +FROM public.ecr.aws/docker/library/ruby:3.0-alpine + +ENV DEBIAN_FRONTEND=noninteractive + +# Set timezone to UTC by default +RUN ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime + +# Upgrade RubyGems and Bundler +RUN gem update --system 3.4.1 +RUN gem install bundler -v '~> 2.3.26' +RUN mkdir -p "$GEM_HOME" && chmod -R 777 "$GEM_HOME" +ENV BUNDLE_SILENCE_ROOT_WARNING 1 + +# Setup directory +RUN mkdir /app +WORKDIR /app + +# Add files +COPY lib_injection_rails_app /app + +# Install gems +RUN bundle install + +# Set entrypoint +ENTRYPOINT ["/bin/bash", "-c"] + +CMD ["bin/rails server -b 0.0.0.0 -p 18080"] diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.ruby_3_1-alpine b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.ruby_3_1-alpine new file mode 100644 index 00000000000..27c3167d169 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.ruby_3_1-alpine @@ -0,0 +1,27 @@ +FROM public.ecr.aws/docker/library/ruby:3.1-alpine + +ENV DEBIAN_FRONTEND=noninteractive + +# Set timezone to UTC by default +RUN ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime + +# Upgrade RubyGems and Bundler +RUN gem update --system 3.4.1 +RUN gem install bundler -v '~> 2.3.26' +RUN mkdir -p "$GEM_HOME" && chmod -R 777 "$GEM_HOME" +ENV BUNDLE_SILENCE_ROOT_WARNING 1 + +# Setup directory +RUN mkdir /app +WORKDIR /app + +# Add files +COPY lib_injection_rails_app /app + +# Install gems +RUN bundle install + +# Set entrypoint +ENTRYPOINT ["/bin/bash", "-c"] + +CMD ["bin/rails server -b 0.0.0.0 -p 18080"] diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.ruby_3_2-alpine b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.ruby_3_2-alpine new file mode 100644 index 00000000000..56dee574121 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/Dockerfile.ruby_3_2-alpine @@ -0,0 +1,27 @@ +FROM public.ecr.aws/docker/library/ruby:3.2-alpine + +ENV DEBIAN_FRONTEND=noninteractive + +# Set timezone to UTC by default +RUN ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime + +# Upgrade RubyGems and Bundler +RUN gem update --system 3.4.1 +RUN gem install bundler -v '~> 2.3.26' +RUN mkdir -p "$GEM_HOME" && chmod -R 777 "$GEM_HOME" +ENV BUNDLE_SILENCE_ROOT_WARNING 1 + +# Setup directory +RUN mkdir /app +WORKDIR /app + +# Add files +COPY lib_injection_rails_app /app + +# Install gems +RUN bundle install + +# Set entrypoint +ENTRYPOINT ["/bin/bash", "-c"] + +CMD ["bin/rails server -b 0.0.0.0 -p 18080"] diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/docker-compose.yml b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/docker-compose.yml new file mode 100644 index 00000000000..864d9125eb5 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/docker-compose.yml @@ -0,0 +1,53 @@ +version: '2' + +services: + reverseproxy: + image: reverseproxy:latest + ports: + - 5985:8080 + restart: always + build: + context: . + dockerfile: Dockerfile.reverseproxy + healthcheck: + test: "curl -f http://localhost:8080" + + ruby_3_2: + env_file: "scenario_app.env" + image: system-tests/ruby_3_2:latest + restart: always + build: + context: . + dockerfile: Dockerfile.ruby_3_2-alpine + healthcheck: + test: "curl -f http://localhost:18080" + + ruby_3_1: + env_file: "scenario_app.env" + image: system-tests/ruby_3_1:latest + restart: always + build: + context: . + dockerfile: Dockerfile.ruby_3_1-alpine + healthcheck: + test: "curl -f http://localhost:18080" + + ruby_3_0: + env_file: "scenario_app.env" + image: system-tests/ruby_3_0:latest + restart: always + build: + context: . + dockerfile: Dockerfile.ruby_3_0-alpine + healthcheck: + test: "curl -f http://localhost:18080" + + ruby_2_7: + env_file: "scenario_app.env" + image: system-tests/ruby_2_7:latest + restart: always + build: + context: . + dockerfile: Dockerfile.ruby_2_7-alpine + healthcheck: + test: "curl -f http://localhost:18080" diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/nginx.conf b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/nginx.conf new file mode 100644 index 00000000000..88ce9b08187 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multialpine/nginx.conf @@ -0,0 +1,71 @@ +worker_processes 1; + +events { worker_connections 1024; } + + +http { + + log_format compression '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $upstream_addr ' + '"$http_referer" "$http_user_agent" "$gzip_ratio"'; + + upstream ruby_3_2_app { + server ruby_3_2:18080; + } + upstream ruby_3_1_app { + server ruby_3_1:18080; + } + upstream ruby_3_0_app { + server ruby_3_0:18080; + } + upstream ruby_2_7_app { + server ruby_2_7:18080; + } + server { + listen 8080; + access_log /var/log/nginx/access.log compression; + + location / { + default_type application/json; + return 200 "{ + 'app_type':'multicontainer', + 'apps':[{ + 'runtime':'3.2', + 'type':'alpine', + 'url':'/ruby_3_2/' + },{ + 'runtime':'3.1', + 'type':'alpine', + 'url':'/ruby_3_1/' + },{ + 'runtime':'3.0', + 'type':'alpine', + 'url':'/ruby_3_0/' + },{ + 'runtime':'2.7', + 'type':'alpine', + 'url':'/ruby_2_7/' + } + + ] + }"; + } + + location /ruby_3_2/ { + proxy_pass http://ruby_3_2_app/; + proxy_redirect off; + } + location /ruby_3_1/ { + proxy_pass http://ruby_3_1_app/; + proxy_redirect off; + } + location /ruby_3_0/ { + proxy_pass http://ruby_3_0_app/; + proxy_redirect off; + } + location /ruby_2_7/ { + proxy_pass http://ruby_2_7_app/; + proxy_redirect off; + } + } +} diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.reverseproxy b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.reverseproxy new file mode 100644 index 00000000000..82cdb622233 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.reverseproxy @@ -0,0 +1,3 @@ +FROM public.ecr.aws/nginx/nginx:stable-perl + +COPY nginx.conf /etc/nginx/nginx.conf \ No newline at end of file diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.ruby_2_7 b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.ruby_2_7 new file mode 100644 index 00000000000..98804bcc73a --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.ruby_2_7 @@ -0,0 +1,46 @@ +FROM public.ecr.aws/docker/library/ruby:2.7 + +ENV DEBIAN_FRONTEND=noninteractive + +# Install prerequisites +RUN set -ex && \ + echo "===> Installing dependencies" && \ + apt-get -y update && \ + apt-get install -y --force-yes --no-install-recommends \ + curl wget tar gzip gnupg apt-transport-https ca-certificates tzdata locales && \ + \ + echo "===> Installing database libraries" && \ + apt-get install -y --force-yes --no-install-recommends sqlite3 && \ + \ + echo "===> Installing dev tools" && \ + mkdir -p /usr/share/man/man1 && \ + apt-get install -y --force-yes --no-install-recommends \ + sudo git openssh-client rsync vim \ + net-tools netcat-traditional parallel unzip zip bzip2 && \ + \ + echo "===> Cleaning up" && \ + rm -rf /var/lib/apt/lists/*; + +# Set timezone to UTC by default +RUN ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime + +# Upgrade RubyGems and Bundler +RUN gem update --system 3.4.1 +RUN gem install bundler -v '~> 2.3.26' +RUN mkdir -p "$GEM_HOME" && chmod -R 777 "$GEM_HOME" +ENV BUNDLE_SILENCE_ROOT_WARNING 1 + +# Setup directory +RUN mkdir /app +WORKDIR /app + +# Add files +COPY lib_injection_rails_app /app + +# Install gems +RUN bundle install + +# Set entrypoint +ENTRYPOINT ["/bin/bash", "-c"] + +CMD ["bin/rails server -b 0.0.0.0 -p 18080"] diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.ruby_3_0 b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.ruby_3_0 new file mode 100644 index 00000000000..14ab84a309e --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.ruby_3_0 @@ -0,0 +1,46 @@ +FROM public.ecr.aws/docker/library/ruby:3.0 + +ENV DEBIAN_FRONTEND=noninteractive + +# Install prerequisites +RUN set -ex && \ + echo "===> Installing dependencies" && \ + apt-get -y update && \ + apt-get install -y --force-yes --no-install-recommends \ + curl wget tar gzip gnupg apt-transport-https ca-certificates tzdata locales && \ + \ + echo "===> Installing database libraries" && \ + apt-get install -y --force-yes --no-install-recommends sqlite3 && \ + \ + echo "===> Installing dev tools" && \ + mkdir -p /usr/share/man/man1 && \ + apt-get install -y --force-yes --no-install-recommends \ + sudo git openssh-client rsync vim \ + net-tools netcat-traditional parallel unzip zip bzip2 && \ + \ + echo "===> Cleaning up" && \ + rm -rf /var/lib/apt/lists/*; + +# Set timezone to UTC by default +RUN ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime + +# Upgrade RubyGems and Bundler +RUN gem update --system 3.4.1 +RUN gem install bundler -v '~> 2.3.26' +RUN mkdir -p "$GEM_HOME" && chmod -R 777 "$GEM_HOME" +ENV BUNDLE_SILENCE_ROOT_WARNING 1 + +# Setup directory +RUN mkdir /app +WORKDIR /app + +# Add files +COPY lib_injection_rails_app /app + +# Install gems +RUN bundle install + +# Set entrypoint +ENTRYPOINT ["/bin/bash", "-c"] + +CMD ["bin/rails server -b 0.0.0.0 -p 18080"] diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.ruby_3_1 b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.ruby_3_1 new file mode 100644 index 00000000000..cd538d21bab --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.ruby_3_1 @@ -0,0 +1,46 @@ +FROM public.ecr.aws/docker/library/ruby:3.1 + +ENV DEBIAN_FRONTEND=noninteractive + +# Install prerequisites +RUN set -ex && \ + echo "===> Installing dependencies" && \ + apt-get -y update && \ + apt-get install -y --force-yes --no-install-recommends \ + curl wget tar gzip gnupg apt-transport-https ca-certificates tzdata locales && \ + \ + echo "===> Installing database libraries" && \ + apt-get install -y --force-yes --no-install-recommends sqlite3 && \ + \ + echo "===> Installing dev tools" && \ + mkdir -p /usr/share/man/man1 && \ + apt-get install -y --force-yes --no-install-recommends \ + sudo git openssh-client rsync vim \ + net-tools netcat-traditional parallel unzip zip bzip2 && \ + \ + echo "===> Cleaning up" && \ + rm -rf /var/lib/apt/lists/*; + +# Set timezone to UTC by default +RUN ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime + +# Upgrade RubyGems and Bundler +RUN gem update --system 3.4.1 +RUN gem install bundler -v '~> 2.3.26' +RUN mkdir -p "$GEM_HOME" && chmod -R 777 "$GEM_HOME" +ENV BUNDLE_SILENCE_ROOT_WARNING 1 + +# Setup directory +RUN mkdir /app +WORKDIR /app + +# Add files +COPY lib_injection_rails_app /app + +# Install gems +RUN bundle install + +# Set entrypoint +ENTRYPOINT ["/bin/bash", "-c"] + +CMD ["bin/rails server -b 0.0.0.0 -p 18080"] diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.ruby_3_2 b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.ruby_3_2 new file mode 100644 index 00000000000..353fe878ef2 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/Dockerfile.ruby_3_2 @@ -0,0 +1,46 @@ +FROM public.ecr.aws/docker/library/ruby:3.2 + +ENV DEBIAN_FRONTEND=noninteractive + +# Install prerequisites +RUN set -ex && \ + echo "===> Installing dependencies" && \ + apt-get -y update && \ + apt-get install -y --force-yes --no-install-recommends \ + curl wget tar gzip gnupg apt-transport-https ca-certificates tzdata locales && \ + \ + echo "===> Installing database libraries" && \ + apt-get install -y --force-yes --no-install-recommends sqlite3 && \ + \ + echo "===> Installing dev tools" && \ + mkdir -p /usr/share/man/man1 && \ + apt-get install -y --force-yes --no-install-recommends \ + sudo git openssh-client rsync vim \ + net-tools netcat-traditional parallel unzip zip bzip2 && \ + \ + echo "===> Cleaning up" && \ + rm -rf /var/lib/apt/lists/*; + +# Set timezone to UTC by default +RUN ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime + +# Upgrade RubyGems and Bundler +RUN gem update --system 3.4.1 +RUN gem install bundler -v '~> 2.3.26' +RUN mkdir -p "$GEM_HOME" && chmod -R 777 "$GEM_HOME" +ENV BUNDLE_SILENCE_ROOT_WARNING 1 + +# Setup directory +RUN mkdir /app +WORKDIR /app + +# Add files +COPY lib_injection_rails_app /app + +# Install gems +RUN bundle install + +# Set entrypoint +ENTRYPOINT ["/bin/bash", "-c"] + +CMD ["bin/rails server -b 0.0.0.0 -p 18080"] diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/docker-compose.yml b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/docker-compose.yml new file mode 100644 index 00000000000..bd4d175210c --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/docker-compose.yml @@ -0,0 +1,53 @@ +version: '2' + +services: + reverseproxy: + image: reverseproxy:latest + ports: + - 5985:8080 + restart: always + build: + context: . + dockerfile: Dockerfile.reverseproxy + healthcheck: + test: "curl -f http://localhost:8080" + + ruby_3_2: + env_file: "scenario_app.env" + image: system-tests/ruby_3_2:latest + restart: always + build: + context: . + dockerfile: Dockerfile.ruby_3_2 + healthcheck: + test: "curl -f http://localhost:18080/" + + ruby_3_1: + env_file: "scenario_app.env" + image: system-tests/ruby_3_1:latest + restart: always + build: + context: . + dockerfile: Dockerfile.ruby_3_1 + healthcheck: + test: "curl -f http://localhost:18080/" + + ruby_3_0: + env_file: "scenario_app.env" + image: system-tests/ruby_3_0:latest + restart: always + build: + context: . + dockerfile: Dockerfile.ruby_3_0 + healthcheck: + test: "curl -f http://localhost:18080/" + + ruby_2_7: + env_file: "scenario_app.env" + image: system-tests/ruby_2_7:latest + restart: always + build: + context: . + dockerfile: Dockerfile.ruby_2_7 + healthcheck: + test: "curl -f http://localhost:18080/" diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/nginx.conf b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/nginx.conf new file mode 100644 index 00000000000..15faeaf75f1 --- /dev/null +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby-multicontainer/nginx.conf @@ -0,0 +1,71 @@ +worker_processes 1; + +events { worker_connections 1024; } + + +http { + + log_format compression '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $upstream_addr ' + '"$http_referer" "$http_user_agent" "$gzip_ratio"'; + + upstream ruby_3_2_app { + server ruby_3_2:18080; + } + upstream ruby_3_1_app { + server ruby_3_1:18080; + } + upstream ruby_3_0_app { + server ruby_3_0:18080; + } + upstream ruby_2_7_app { + server ruby_2_7:18080; + } + server { + listen 8080; + access_log /var/log/nginx/access.log compression; + + location / { + default_type application/json; + return 200 "{ + 'app_type':'multicontainer', + 'apps':[{ + 'runtime':'3.2', + 'type':'container', + 'url':'/ruby_3_2/' + },{ + 'runtime':'3.1', + 'type':'container', + 'url':'/ruby_3_1/' + },{ + 'runtime':'3.0', + 'type':'container', + 'url':'/ruby_3_0/' + },{ + 'runtime':'2.7', + 'type':'container', + 'url':'/ruby_2_7/' + } + + ] + }"; + } + + location /ruby_3_2/ { + proxy_pass http://ruby_3_2_app/; + proxy_redirect off; + } + location /ruby_3_1/ { + proxy_pass http://ruby_3_1_app/; + proxy_redirect off; + } + location /ruby_3_0/ { + proxy_pass http://ruby_3_0_app/; + proxy_redirect off; + } + location /ruby_2_7/ { + proxy_pass http://ruby_2_7_app/; + proxy_redirect off; + } + } +} diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby/test-app-ruby_run.sh b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby/test-app-ruby_run.sh index 83e473940ca..6d21817a8d3 100755 --- a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby/test-app-ruby_run.sh +++ b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby/test-app-ruby_run.sh @@ -1,28 +1,13 @@ #!/bin/bash -echo "START RUN APP" +echo "START ruby APP" # shellcheck disable=SC2035 sudo chmod -R 755 * - +export PATH=~/.rbenv/bin/:~/.rbenv/shims:$PATH +rbenv local 3.0.2 DD_INSTRUMENT_SERVICE_WITH_APM=false bundle install +current_user=$(whoami) +sed -i "s/SSI_USER/$current_user/g" test-app.service +./create_and_run_app_service.sh "/home/$current_user/.rbenv/shims/rails server -b 0.0.0.0 -p 5985" -# shellcheck disable=SC2035 -sudo cp -R * /home/datadog - -# shellcheck disable=SC2035 -sudo chmod -R 755 /home/datadog - -sudo chown -R datadog:datadog /home/datadog -#Ubuntu work without this, but Amazon Linux needs bundle install executed with datadog user -sudo su - datadog -c 'DD_INSTRUMENT_SERVICE_WITH_APM=false bundle install' -sudo cp test-app.service /etc/systemd/system/test-app.service -sudo systemctl daemon-reload -sudo systemctl enable test-app.service -sudo systemctl start test-app.service -sudo systemctl status test-app.service - -#TODO Extract the output file in other step -sleep 5 -sudo cat /home/datadog/app-std.out - -echo "RUN DONE" \ No newline at end of file +echo "RUN ruby DONE" diff --git a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby/test-app.service b/utils/build/virtual_machine/weblogs/ruby/test-app-ruby/test-app.service deleted file mode 100644 index 7d931a8cfad..00000000000 --- a/utils/build/virtual_machine/weblogs/ruby/test-app-ruby/test-app.service +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=Ruby Weblog App Service -After=syslog.target network.target - -[Service] -SuccessExitStatus=143 - -User=datadog - -Type=simple - -Environment=DD_APM_INSTRUMENTATION_DEBUG=TRUE -WorkingDirectory=/home/datadog -ExecStart=/bin/bash -c 'rails server -b 0.0.0.0 -p 5985 >> /home/datadog/app-std.out 2>&1 > /var/log/datadog_weblog/app.log 2>&1 Optional[_CGroupInfo] - """ - Parse a new :class:`CGroupInfo` from the provided line + """Parse a new :class:`CGroupInfo` from the provided line :param line: A line from a cgroup file (e.g. /proc/self/cgroup) to parse information from :type line: str :returns: A :class:`CGroupInfo` object with all parsed data, if the line is valid, otherwise `None` diff --git a/utils/dd_constants.py b/utils/dd_constants.py index a151e69469d..5934b237e6e 100644 --- a/utils/dd_constants.py +++ b/utils/dd_constants.py @@ -1,4 +1,6 @@ from enum import IntEnum +from opentelemetry.trace import SpanKind # noqa: F401 +from opentelemetry.trace import StatusCode # noqa: F401 # Key used in the metrics map to indicate tracer sampling priority @@ -27,9 +29,39 @@ class RemoteConfigApplyState(IntEnum): - """ https://docs.google.com/document/d/1bUVtEpXNTkIGvLxzkNYCxQzP2X9EK9HMBLHWXr_5KLM/edit#heading=h.vy1jegxy7cuc """ + """https://docs.google.com/document/d/1bUVtEpXNTkIGvLxzkNYCxQzP2X9EK9HMBLHWXr_5KLM/edit#heading=h.vy1jegxy7cuc""" UNKNOWN = 0 UNACKNOWLEDGED = 1 ACKNOWLEDGED = 2 ERROR = 3 + + +class Capabilities(IntEnum): + ASM_ACTIVATION = 1 + ASM_IP_BLOCKING = 2 + ASM_DD_RULES = 3 + ASM_EXCLUSIONS = 4 + ASM_REQUEST_BLOCKING = 5 + ASM_ASM_RESPONSE_BLOCKING = 6 + ASM_USER_BLOCKING = 7 + ASM_CUSTOM_RULES = 8 + ASM_CUSTOM_BLOCKING_RESPONSE = 9 + ASM_TRUSTED_IPS = 10 + ASM_API_SECURITY_SAMPLE_RATE = 11 + APM_TRACING_SAMPLE_RATE = 12 + APM_TRACING_LOGS_INJECTION = 13 + APM_TRACING_HTTP_HEADER_TAGS = 14 + APM_TRACING_CUSTOM_TAGS = 15 + APM_TRACING_ENABLED = 19 + ASM_RASP_SQLI = 21 + ASM_RASP_LFI = 22 + ASM_RASP_SSRF = 23 + ASM_RASP_SHI = 24 + APM_TRACING_SAMPLE_RULES = 29 + ASM_AUTO_USER_INSTRUM_MODE = 31 + ASM_ENDPOINT_FINGERPRINT = 32 + ASM_SESSION_FINGERPRINT = 33 + ASM_NETWORK_FINGERPRINT = 34 + ASM_HEADER_FINGERPRINT = 35 + ASM_RASP_CMDI = 37 diff --git a/utils/docker_ssi/__init__.py b/utils/docker_ssi/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/docker_ssi/docker_ssi_definitions.py b/utils/docker_ssi/docker_ssi_definitions.py new file mode 100644 index 00000000000..228890bc5b5 --- /dev/null +++ b/utils/docker_ssi/docker_ssi_definitions.py @@ -0,0 +1,345 @@ +LINUX_AMD64 = "linux/amd64" +LINUX_ARM64 = "linux/arm64" + +try: + from utils.docker_ssi.docker_ssi_model import DockerImage, RuntimeInstallableVersion, WeblogDescriptor +except ImportError: + from docker_ssi_model import DockerImage, RuntimeInstallableVersion, WeblogDescriptor + + +class SupportedImages: + """All supported images""" + + def __init__(self) -> None: + # Try to set the same name as utils/_context/virtual_machines.py + self.UBUNTU_22_AMD64 = DockerImage("Ubuntu_22", "ubuntu:22.04", LINUX_AMD64) + self.UBUNTU_22_ARM64 = DockerImage("Ubuntu_22", "ubuntu:22.04", LINUX_ARM64) + self.UBUNTU_16_AMD64 = DockerImage("Ubuntu_16", "ubuntu:16.04", LINUX_AMD64) + self.UBUNTU_16_ARM64 = DockerImage("Ubuntu_16", "ubuntu:16.04", LINUX_ARM64) + self.CENTOS_7_AMD64 = DockerImage("CentOS_7", "centos:7", LINUX_AMD64) + self.ORACLELINUX_9_ARM64 = DockerImage("OracleLinux_9", "oraclelinux:9", LINUX_ARM64) + self.ORACLELINUX_9_AMD64 = DockerImage("OracleLinux_9", "oraclelinux:9", LINUX_AMD64) + self.ORACLELINUX_8_ARM64 = DockerImage("OracleLinux_8_10", "oraclelinux:8.10", LINUX_ARM64) + self.ORACLELINUX_8_AMD64 = DockerImage("OracleLinux_8_10", "oraclelinux:8.10", LINUX_AMD64) + + self.ALMALINUX_9_ARM64 = DockerImage("AlmaLinux_9", "almalinux:9.4", LINUX_ARM64) + self.ALMALINUX_9_AMD64 = DockerImage("AlmaLinux_9", "almalinux:9.4", LINUX_AMD64) + self.ALMALINUX_8_ARM64 = DockerImage("AlmaLinux_8", "almalinux:8.10", LINUX_ARM64) + self.ALMALINUX_8_AMD64 = DockerImage("AlmaLinux_8", "almalinux:8.10", LINUX_AMD64) + + # Currently bugged + # DockerImage("centos:7", LINUX_ARM64, short_name="centos_7") + # DockerImage("alpine:3", LINUX_AMD64, short_name="alpine_3"), + # DockerImage("alpine:3", LINUX_ARM64, short_name="alpine_3"), + self.TOMCAT_9_AMD64 = DockerImage("Tomcat_9", "tomcat:9", LINUX_AMD64) + self.TOMCAT_9_ARM64 = DockerImage("Tomcat_9", "tomcat:9", LINUX_ARM64) + self.WEBSPHERE_AMD64 = DockerImage("Websphere", "icr.io/appcafe/websphere-traditional", LINUX_AMD64) + self.JBOSS_AMD64 = DockerImage("Wildfly", "quay.io/wildfly/wildfly:26.1.2.Final", LINUX_AMD64) + + def get_internal_name_from_base_image(self, base_image, arch): + for image in self.__dict__.values(): + if image.tag == base_image and image.platform == arch: + return image.internal_name + raise ValueError(f"Image {base_image} not supported") + + +class JavaRuntimeInstallableVersions: + """Java runtime versions that can be installed automatically""" + + JAVA_22 = RuntimeInstallableVersion("JAVA_22", "22.0.2-zulu") + JAVA_21 = RuntimeInstallableVersion("JAVA_21", "21.0.4-zulu") + JAVA_17 = RuntimeInstallableVersion("JAVA_17", "17.0.12-zulu") + JAVA_11 = RuntimeInstallableVersion("JAVA_11", "11.0.24-zulu") + + @staticmethod + def get_all_versions(): + return [ + JavaRuntimeInstallableVersions.JAVA_22, + JavaRuntimeInstallableVersions.JAVA_21, + JavaRuntimeInstallableVersions.JAVA_17, + JavaRuntimeInstallableVersions.JAVA_11, + ] + + @staticmethod + def get_version_id(version): + for version_check in JavaRuntimeInstallableVersions.get_all_versions(): + if version_check.version == version: + return version_check.version_id + raise ValueError(f"Java version {version} not supported") + + +class PHPRuntimeInstallableVersions: + """PHP runtime versions that can be installed automatically""" + + PHP56 = RuntimeInstallableVersion("PHP56", "5.6") # Not supported (EOL runtime) + PHP70 = RuntimeInstallableVersion("PHP70", "7.0") + PHP71 = RuntimeInstallableVersion("PHP71", "7.1") + PHP72 = RuntimeInstallableVersion("PHP72", "7.2") + PHP73 = RuntimeInstallableVersion("PHP73", "7.3") + PHP74 = RuntimeInstallableVersion("PHP74", "7.4") + PHP80 = RuntimeInstallableVersion("PHP80", "8.0") + PHP81 = RuntimeInstallableVersion("PHP81", "8.1") + PHP82 = RuntimeInstallableVersion("PHP82", "8.2") + PHP83 = RuntimeInstallableVersion("PHP83", "8.3") + + @staticmethod + def get_all_versions(): + return [ + PHPRuntimeInstallableVersions.PHP56, + PHPRuntimeInstallableVersions.PHP70, + PHPRuntimeInstallableVersions.PHP71, + PHPRuntimeInstallableVersions.PHP72, + PHPRuntimeInstallableVersions.PHP73, + PHPRuntimeInstallableVersions.PHP74, + PHPRuntimeInstallableVersions.PHP80, + PHPRuntimeInstallableVersions.PHP81, + PHPRuntimeInstallableVersions.PHP82, + PHPRuntimeInstallableVersions.PHP83, + ] + + @staticmethod + def get_version_id(version): + for version_check in PHPRuntimeInstallableVersions.get_all_versions(): + if version_check.version == version: + return version_check.version_id + raise ValueError(f"PHP version {version} not supported") + + +class PythonRuntimeInstallableVersions: + """Python runtime versions that can be installed automatically""" + + PY36 = RuntimeInstallableVersion("PY36", "3.6.15") # Not supported (EOL runtime) + PY37 = RuntimeInstallableVersion("PY37", "3.7.16") + PY38 = RuntimeInstallableVersion("PY38", "3.8.20") + PY39 = RuntimeInstallableVersion("PY39", "3.9.20") + PY310 = RuntimeInstallableVersion("PY310", "3.10.15") + PY311 = RuntimeInstallableVersion("PY311", "3.11.10") + PY312 = RuntimeInstallableVersion("PY312", "3.12.7") + + @staticmethod + def get_all_versions(): + return [ + PythonRuntimeInstallableVersions.PY36, + PythonRuntimeInstallableVersions.PY37, + PythonRuntimeInstallableVersions.PY38, + PythonRuntimeInstallableVersions.PY39, + PythonRuntimeInstallableVersions.PY310, + PythonRuntimeInstallableVersions.PY311, + PythonRuntimeInstallableVersions.PY312, + ] + + @staticmethod + def get_version_id(version): + for version_check in PythonRuntimeInstallableVersions.get_all_versions(): + if version_check.version == version: + return version_check.version_id + raise ValueError(f"Python version {version} not supported") + + +class JSRuntimeInstallableVersions: + """Node.js runtime versions that can be installed automatically""" + + JS1200 = RuntimeInstallableVersion("JS1200", "12.0") + JS1222 = RuntimeInstallableVersion("JS1222", "12.22") + JS1400 = RuntimeInstallableVersion("JS1400", "14.0") + JS1421 = RuntimeInstallableVersion("JS1421", "14.21") + JS1600 = RuntimeInstallableVersion("JS1600", "16.0") + JS1620 = RuntimeInstallableVersion("JS1620", "16.20") + JS1800 = RuntimeInstallableVersion("JS1800", "18.0") + JS1820 = RuntimeInstallableVersion("JS1820", "18.20") + JS2000 = RuntimeInstallableVersion("JS2000", "20.0") + JS2018 = RuntimeInstallableVersion("JS2018", "20.18") + JS2200 = RuntimeInstallableVersion("JS2200", "22.0") + JS2211 = RuntimeInstallableVersion("JS2211", "22.11") + JS2300 = RuntimeInstallableVersion("JS2300", "23.0") + JS2303 = RuntimeInstallableVersion("JS2303", "23.3") + + @staticmethod + def get_all_versions(): + return [ + JSRuntimeInstallableVersions.JS1200, + JSRuntimeInstallableVersions.JS1222, + JSRuntimeInstallableVersions.JS1400, + JSRuntimeInstallableVersions.JS1421, + JSRuntimeInstallableVersions.JS1600, + JSRuntimeInstallableVersions.JS1620, + JSRuntimeInstallableVersions.JS1800, + JSRuntimeInstallableVersions.JS1820, + JSRuntimeInstallableVersions.JS2000, + JSRuntimeInstallableVersions.JS2018, + JSRuntimeInstallableVersions.JS2200, + JSRuntimeInstallableVersions.JS2211, + JSRuntimeInstallableVersions.JS2300, + JSRuntimeInstallableVersions.JS2303, + ] + + @staticmethod + def get_version_id(version): + for version_check in JSRuntimeInstallableVersions.get_all_versions(): + if version_check.version == version: + return version_check.version_id + raise ValueError(f"Node.js version {version} not supported") + + +class DotnetRuntimeInstallableVersions: + """Python runtime versions that can be installed automatically""" + + DOTNET70 = RuntimeInstallableVersion("DOTNET70", "7.0.410") + + @staticmethod + def get_all_versions(): + return [ + DotnetRuntimeInstallableVersions.DOTNET70, + ] + + @staticmethod + def get_version_id(version): + for version_check in DotnetRuntimeInstallableVersions.get_all_versions(): + if version_check.version == version: + return version_check.version_id + raise ValueError(f".NET version {version} not supported") + + +# HERE ADD YOUR WEBLOG DEFINITION: SUPPORTED IMAGES AND INSTALABLE RUNTIME VERSIONS +# Maybe a weblog app contains preinstalled language runtime, in this case we define the weblog without runtime version +JETTY_APP = WeblogDescriptor( + "jetty-app", + "java", + [ + SupportedImages().UBUNTU_22_AMD64.with_allowed_runtime_versions( + JavaRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().UBUNTU_22_ARM64.with_allowed_runtime_versions( + JavaRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().UBUNTU_16_AMD64.with_allowed_runtime_versions( + JavaRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().UBUNTU_16_ARM64.with_allowed_runtime_versions( + JavaRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ORACLELINUX_9_AMD64.with_allowed_runtime_versions( + JavaRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ORACLELINUX_9_ARM64.with_allowed_runtime_versions( + JavaRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ORACLELINUX_8_AMD64.with_allowed_runtime_versions( + JavaRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ORACLELINUX_8_ARM64.with_allowed_runtime_versions( + JavaRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ALMALINUX_9_AMD64.with_allowed_runtime_versions( + JavaRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ALMALINUX_9_ARM64.with_allowed_runtime_versions( + JavaRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ALMALINUX_8_AMD64.with_allowed_runtime_versions( + JavaRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ALMALINUX_8_ARM64.with_allowed_runtime_versions( + JavaRuntimeInstallableVersions.get_all_versions() + ), + # Commented due to APMON-1491 + # SupportedImages().CENTOS_7_AMD64.with_allowed_runtime_versions( + # JavaRuntimeInstallableVersions.get_all_versions() + # ), + ], +) + + +TOMCAT_APP = WeblogDescriptor("tomcat-app", "java", [SupportedImages().TOMCAT_9_ARM64]) +JAVA7_APP = WeblogDescriptor("java7-app", "java", [SupportedImages().UBUNTU_22_ARM64]) +WEBSPHERE_APP = WeblogDescriptor("websphere-app", "java", [SupportedImages().WEBSPHERE_AMD64]) +JBOSS_APP = WeblogDescriptor("jboss-app", "java", [SupportedImages().JBOSS_AMD64]) + +PHP_APP = WeblogDescriptor( + "php-app", + "php", + [ + SupportedImages().UBUNTU_22_AMD64.with_allowed_runtime_versions( + PHPRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().UBUNTU_22_ARM64.with_allowed_runtime_versions( + PHPRuntimeInstallableVersions.get_all_versions() + ), + ], +) + +PY_APP = WeblogDescriptor( + "py-app", + "python", + [ + SupportedImages().UBUNTU_22_ARM64.with_allowed_runtime_versions( + PythonRuntimeInstallableVersions.get_all_versions() + ), + ], +) + +JS_APP = WeblogDescriptor( + "js-app", + "nodejs", + [ + SupportedImages().UBUNTU_22_AMD64.with_allowed_runtime_versions( + JSRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().UBUNTU_22_ARM64.with_allowed_runtime_versions( + JSRuntimeInstallableVersions.get_all_versions() + ), + ], +) + +DOTNET_APP = WeblogDescriptor( + "dotnet-app", + "dotnet", + [ + SupportedImages().UBUNTU_22_AMD64.with_allowed_runtime_versions( + DotnetRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().UBUNTU_22_ARM64.with_allowed_runtime_versions( + DotnetRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().UBUNTU_16_AMD64.with_allowed_runtime_versions( + DotnetRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ORACLELINUX_8_AMD64.with_allowed_runtime_versions( + DotnetRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ORACLELINUX_8_ARM64.with_allowed_runtime_versions( + DotnetRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ORACLELINUX_9_AMD64.with_allowed_runtime_versions( + DotnetRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ORACLELINUX_9_ARM64.with_allowed_runtime_versions( + DotnetRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ALMALINUX_8_AMD64.with_allowed_runtime_versions( + DotnetRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ALMALINUX_8_ARM64.with_allowed_runtime_versions( + DotnetRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ALMALINUX_9_AMD64.with_allowed_runtime_versions( + DotnetRuntimeInstallableVersions.get_all_versions() + ), + SupportedImages().ALMALINUX_9_ARM64.with_allowed_runtime_versions( + DotnetRuntimeInstallableVersions.get_all_versions() + ), + ], +) + +# HERE ADD YOUR WEBLOG DEFINITION TO THE LIST +ALL_WEBLOGS = [ + JETTY_APP, + TOMCAT_APP, + JAVA7_APP, + WEBSPHERE_APP, + JBOSS_APP, + PHP_APP, + PY_APP, + JS_APP, + DOTNET_APP, +] diff --git a/utils/docker_ssi/docker_ssi_matrix_builder.py b/utils/docker_ssi/docker_ssi_matrix_builder.py new file mode 100644 index 00000000000..5edff117c52 --- /dev/null +++ b/utils/docker_ssi/docker_ssi_matrix_builder.py @@ -0,0 +1,126 @@ +import json +import yaml +import argparse + + +from docker_ssi_definitions import ALL_WEBLOGS + + +def generate_gitlab_pipeline(languages): + pipeline = { + "stages": ["DOCKER_SSI"], + "configure": { + "image": "486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/test-infra-definitions/runner:6dd143866d67", + "tags": ["arch:amd64"], + "stage": "DOCKER_SSI", + "dependencies": [], + "script": [ + 'export FP_IMPORT_URL=$(aws ssm get-parameter --region us-east-1 --name ci.system-tests.fp-import-url --with-decryption --query "Parameter.Value" --out text)', + 'export FP_API_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.system-tests.fp-api-key --with-decryption --query "Parameter.Value" --out text)', + 'echo "FP_IMPORT_URL=${FP_IMPORT_URL}" >> fpd.env', + 'echo "FP_API_KEY=${FP_API_KEY}" >> fpd.env', + ], + "artifacts": {"reports": {"dotenv": "fpd.env"}}, + }, + ".base_ssi_job": { + "image": "registry.ddbuild.io/ci/libdatadog-build/system-tests:48436362", + "script": [ + "./build.sh -i runner", + "source venv/bin/activate", + "echo 'Running SSI tests'", + 'timeout 2700s ./run.sh DOCKER_SSI --ssi-weblog "$weblog" --ssi-library "$TEST_LIBRARY" --ssi-base-image "$base_image" --ssi-arch "$arch" --ssi-installable-runtime "$installable_runtime" --report-run-url ${CI_PIPELINE_URL} --report-environment prod', + ], + "rules": [ + {"if": '$PARENT_PIPELINE_SOURCE == "schedule"', "when": "always"}, + {"when": "manual", "allow_failure": True}, + ], + "after_script": [ + 'SCENARIO_SUFIX=$(echo "DOCKER_SSI" | tr "[:upper:]" "[:lower:]")', + 'REPORTS_PATH="reports/"', + 'mkdir -p "$REPORTS_PATH"', + 'cp -R logs_"${SCENARIO_SUFIX}" $REPORTS_PATH/', + 'cleaned_base_image=$(echo "$base_image" | tr -cd "[:alnum:]_")', + 'cleaned_arch=$(echo "$arch" | tr -cd "[:alnum:]_")', + 'cleaned_runtime=$(echo "$installable_runtime" | tr -cd "[:alnum:]_")', + 'mv "$REPORTS_PATH"/logs_"${SCENARIO_SUFIX}" "$REPORTS_PATH"/logs_"${TEST_LIBRARY}"_"${weblog}"_"${SCENARIO_SUFIX}_${cleaned_base_image}_${cleaned_arch}_${cleaned_runtime}"', + ], + "needs": [{"job": "configure", "artifacts": True}], + "artifacts": {"when": "always", "paths": ["reports/"]}, + }, + } + # Add FPD push script + pipeline[".base_ssi_job"]["after_script"].extend(_generate_fpd_gitlab_script()) + + for language in languages: + pipeline["stages"].append(language if len(languages) > 1 else "DOCKER_SSI") + matrix = [] + + filtered = [weblog for weblog in ALL_WEBLOGS if weblog.library == language] + for weblog in filtered: + weblog_matrix = weblog.get_matrix() + if not weblog_matrix: + continue + for test in weblog_matrix: + if test["arch"] == "linux/amd64": + test["runner"] = "docker" + else: + test["runner"] = "docker-arm" + test.pop("unique_name", None) + matrix.append(test) + if matrix: + pipeline[language] = { + "extends": ".base_ssi_job", + "tags": ["runner:$runner"], + "stage": language if len(languages) > 1 else "DOCKER_SSI", + "allow_failure": True, + "variables": {"TEST_LIBRARY": language}, + "parallel": {"matrix": matrix}, + } + return pipeline + + +def _generate_fpd_gitlab_script(): + fpd_push_script = [ + 'if [ "$CI_COMMIT_BRANCH" = "main" ]; then', + "for folder in reports/logs*/ ; do", + ' echo "Checking folder: ${folder}"', + " for filename in ./${folder}feature_parity.json; do", + " if [ -e ${filename} ]", + " then", + ' echo "Processing report: ${filename}"', + ' curl -X POST ${FP_IMPORT_URL} --fail --header "Content-Type: application/json" --header "FP_API_KEY: ${FP_API_KEY}" --data "@${filename}" --include', + " fi", + " done", + "done", + "fi", + ] + return fpd_push_script + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--format", required=True, type=str, choices=["json", "yaml"], help="json or yaml") + parser.add_argument("--output-file", required=False, type=str) + parser.add_argument("--language", required=False, type=str, help="Only generate config for single language") + + args = parser.parse_args() + if args.language: + languages = [args.language] + else: + languages = ["java", "python", "nodejs", "dotnet", "ruby", "php"] + + pipeline = generate_gitlab_pipeline(languages) + + output = ( + json.dumps(pipeline, sort_keys=False) + if args.format == "json" + else yaml.dump(pipeline, sort_keys=False, default_flow_style=False) + ) + print(output) + if args.output_file is not None: + with open(args.output_file, "w") as f: + f.write(output) + + +if __name__ == "__main__": + main() diff --git a/utils/docker_ssi/docker_ssi_matrix_utils.py b/utils/docker_ssi/docker_ssi_matrix_utils.py new file mode 100644 index 00000000000..f5f0bdca33d --- /dev/null +++ b/utils/docker_ssi/docker_ssi_matrix_utils.py @@ -0,0 +1,23 @@ +from utils.docker_ssi.docker_ssi_definitions import ( + JavaRuntimeInstallableVersions, + JSRuntimeInstallableVersions, + PHPRuntimeInstallableVersions, + PythonRuntimeInstallableVersions, + DotnetRuntimeInstallableVersions, +) + + +def resolve_runtime_version(library, runtime): + """For installable runtimes, get the version identifier. ie JAVA_11""" + if library == "java": + return JavaRuntimeInstallableVersions.get_version_id(runtime) + elif library == "php": + return PHPRuntimeInstallableVersions.get_version_id(runtime) + elif library == "python": + return PythonRuntimeInstallableVersions.get_version_id(runtime) + elif library == "nodejs": + return JSRuntimeInstallableVersions.get_version_id(runtime) + elif library == "dotnet": + return DotnetRuntimeInstallableVersions.get_version_id(runtime) + + raise ValueError(f"Library {library} not supported") diff --git a/utils/docker_ssi/docker_ssi_model.py b/utils/docker_ssi/docker_ssi_model.py new file mode 100644 index 00000000000..1609b959ebb --- /dev/null +++ b/utils/docker_ssi/docker_ssi_model.py @@ -0,0 +1,74 @@ +class RuntimeInstallableVersion: + """Encapsulates information of the version of the language that can be installed automatically""" + + def __init__(self, version_id, version) -> None: + self.version_id = version_id + self.version = version + + +class DockerImage: + """Encapsulates information of the docker image""" + + def __init__(self, internal_name, tag, platform) -> None: + # Try to set the same name as utils/_context/virtual_machines.py + self.internal_name = internal_name + self.tag = tag + self.platform = platform + self.runtime_versions = [] + + def with_allowed_runtime_versions(self, runtime_versions): + self.runtime_versions = runtime_versions + return self + + def add_allowed_runtime_version(self, runtime_version): + self.runtime_versions.append(runtime_version) + return self + + def tag_name(self): + return self.tag.rsplit("/", 1)[-1] + + def name(self): + return self.tag.replace(":", "_").replace("/", "_").replace(".", "_") + "_" + self.platform.replace("/", "_") + + +class WeblogDescriptor: + """Encapsulates information of the weblog: name, library and + supported images with the supported installable runtime versions + """ + + # see utils._features to check ids + def __init__(self, name, library, supported_images): + self.name = name + self.library = library + self.supported_images = supported_images + + def get_matrix(self): + matrix_combinations = [] + for image in self.supported_images: + if not image.runtime_versions: + matrix_combinations.append( + { + "weblog": self.name, + "base_image": image.tag, + "arch": image.platform, + "installable_runtime": "''", + "unique_name": self.clean_name(f"{self.name}_{image.tag}_{image.platform}"), + }, + ) + else: + for runtime_version in image.runtime_versions: + matrix_combinations.append( + { + "weblog": self.name, + "base_image": image.tag, + "arch": image.platform, + "installable_runtime": runtime_version.version, + "unique_name": self.clean_name( + f"{self.name}_{image.tag}_{image.platform}_{runtime_version.version_id}" + ), + } + ) + return matrix_combinations + + def clean_name(self, tag_to_clean): + return tag_to_clean.replace(":", "_").replace("/", "_").replace(".", "_").replace("-", "_").lower() diff --git a/utils/interfaces/__init__.py b/utils/interfaces/__init__.py index 7188c52e7a1..057442f8c38 100644 --- a/utils/interfaces/__init__.py +++ b/utils/interfaces/__init__.py @@ -7,6 +7,7 @@ from ._library.core import LibraryInterfaceValidator from ._logs import _LibraryStdout, _LibraryDotnetManaged, _AgentStdout, _PostgresStdout from ._open_telemetry import OpenTelemetryInterfaceValidator +from ._test_agent import _TestAgentInterfaceValidator # singletons agent = AgentInterfaceValidator() @@ -17,6 +18,7 @@ backend = _BackendInterfaceValidator(library_interface=library) open_telemetry = OpenTelemetryInterfaceValidator() postgres = _PostgresStdout() +test_agent = _TestAgentInterfaceValidator() python_buddy = LibraryInterfaceValidator("python_buddy") nodejs_buddy = LibraryInterfaceValidator("nodejs_buddy") diff --git a/utils/interfaces/_agent.py b/utils/interfaces/_agent.py index a03763c69a0..fac292abec4 100644 --- a/utils/interfaces/_agent.py +++ b/utils/interfaces/_agent.py @@ -2,9 +2,7 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -""" -This files will validate data flow between agent and backend -""" +"""Validate data flow between agent and backend""" import threading import copy @@ -26,7 +24,6 @@ def ingest_file(self, src_path): return super().ingest_file(src_path) def get_appsec_data(self, request): - rid = get_rid_from_request(request) for data in self.get_data(path_filters="/api/v0.2/traces"): @@ -62,6 +59,9 @@ def assert_use_domain(self, expected_domain): def get_profiling_data(self): yield from self.get_data(path_filters="/api/v2/profile") + def validate_profiling(self, validator, *, success_by_default=False): + self.validate(validator, path_filters="/api/v2/profile", success_by_default=success_by_default) + def validate_appsec(self, request, validator): for data, payload, chunk, span, appsec_data in self.get_appsec_data(request=request): if validator(data, payload, chunk, span, appsec_data): @@ -69,7 +69,7 @@ def validate_appsec(self, request, validator): raise ValueError("No data validate this test") - def get_telemetry_data(self, flatten_message_batches=True): + def get_telemetry_data(self, *, flatten_message_batches=True): all_data = self.get_data(path_filters="/api/v2/apmtelemetry") if flatten_message_batches: yield from all_data @@ -86,6 +86,12 @@ def get_telemetry_data(self, flatten_message_batches=True): else: yield data + def assert_trace_exists(self, request): + for _, _ in self.get_spans(request=request): + return + + raise ValueError(f"No trace has been found for request {get_rid_from_request(request)}") + def assert_headers_presence(self, path_filter, request_headers=(), response_headers=(), check_condition=None): validator = HeadersPresenceValidator(request_headers, response_headers, check_condition) self.validate(validator, path_filters=path_filter, success_by_default=True) @@ -94,7 +100,7 @@ def assert_headers_match(self, path_filter, request_headers=(), response_headers validator = HeadersMatchValidator(request_headers, response_headers, check_condition) self.validate(validator, path_filters=path_filter, success_by_default=True) - def validate_telemetry(self, validator=None, success_by_default=False): + def validate_telemetry(self, validator=None, *, success_by_default=False): def validator_skip_onboarding_event(data): if data["request"]["content"].get("request_type") == "apm-onboarding-event": return None @@ -106,7 +112,7 @@ def validator_skip_onboarding_event(data): path_filters="/api/v2/apmtelemetry", ) - def add_traces_validation(self, validator, success_by_default=False): + def add_traces_validation(self, validator, *, success_by_default=False): self.validate( validator=validator, success_by_default=success_by_default, path_filters=r"/api/v0\.[1-9]+/traces" ) @@ -131,9 +137,7 @@ def get_spans(self, request=None): for payload in content: for chunk in payload["chunks"]: for span in chunk["spans"]: - if rid is None: - yield data, span - elif get_rid_from_span(span) == rid: + if rid is None or get_rid_from_span(span) == rid: yield data, span def get_spans_list(self, request): @@ -141,3 +145,19 @@ def get_spans_list(self, request): def get_dsm_data(self): return self.get_data(path_filters="/api/v0.1/pipeline_stats") + + def get_stats(self, resource=""): + """Attempts to fetch the stats the agent will submit to the backend. + + When a valid request is given, then we filter the stats to the ones sampled + during that request's execution, and only return those. + """ + + for data in self.get_data(path_filters="/api/v0.2/stats"): + client_stats_payloads = data["request"]["content"]["Stats"] + + for client_stats_payload in client_stats_payloads: + for client_stats_buckets in client_stats_payload["Stats"]: + for client_grouped_stat in client_stats_buckets["Stats"]: + if resource == "" or client_grouped_stat["Resource"] == resource: + yield client_grouped_stat diff --git a/utils/interfaces/_backend.py b/utils/interfaces/_backend.py index 851dd3ce6a5..b46cf191fb6 100644 --- a/utils/interfaces/_backend.py +++ b/utils/interfaces/_backend.py @@ -2,7 +2,7 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -""" This files will validate data flow between agent and backend """ +"""Validate data flow between agent and backend""" import json import os @@ -62,7 +62,6 @@ def load_data_from_logs(self): self._init_rid_to_library_trace_ids() def _init_rid_to_library_trace_ids(self): - # Map each request ID to the spans created and submitted during that request call. for _, span in self.library_interface.get_root_spans(): rid = get_rid_from_span(span) @@ -89,15 +88,15 @@ def assert_library_traces_exist(self, request, min_traces_len=1): """ rid = get_rid_from_request(request) - tracesData = list(self._wait_for_request_traces(rid)) - traces = [self._extract_trace_from_backend_response(data["response"]) for data in tracesData] + traces_data = list(self._wait_for_request_traces(rid)) + traces = [self._extract_trace_from_backend_response(data["response"]) for data in traces_data] assert ( len(traces) >= min_traces_len ), f"We only found {len(traces)} traces in the library (tracers), but we expected {min_traces_len}!" return traces def assert_otlp_trace_exist( - self, request: requests.Request, dd_trace_id: str, dd_api_key: str = None, dd_app_key: str = None + self, request: requests.Request, dd_trace_id: str, dd_api_key: str | None = None, dd_app_key: str | None = None ) -> dict: """Attempts to fetch from the backend, ALL the traces that the OpenTelemetry SDKs sent to Datadog during the execution of the given request. @@ -224,8 +223,8 @@ def _request_one(self, method, path, host=None, json_payload=None, dd_api_key=No "path": path, "query": query, "request": {"content": json_payload}, - "response": {"status_code": r.status_code, "content": r.content, "headers": dict(r.headers),}, - "log_filename": f"{self._log_folder}/{self.message_count:03d}_{path.replace('/', '_')}.json", + "response": {"status_code": r.status_code, "content": r.content, "headers": dict(r.headers)}, + "log_filename": f"{self.log_folder}/{self.message_count:03d}_{path.replace('/', '_')}.json", } self.message_count += 1 @@ -271,7 +270,6 @@ def _wait_for_trace(self, rid, trace_id, retries, sleep_interval_multiplier, dd_ ) def _wait_for_request_traces(self, rid, retries=5, sleep_interval_multiplier=2.0): - trace_ids = self._get_trace_ids(rid) logger.info( f"Waiting for {len(trace_ids)} traces to become available from request {rid} with {retries} retries..." @@ -290,7 +288,6 @@ def _extract_trace_from_backend_response(self, response): return trace def _wait_for_event_platform_spans(self, query_filter, limit, retries=5, sleep_interval_multiplier=2.0): - logger.info( f"Waiting until spans (non-empty response) become available with " f"query '{query_filter}' with {retries} retries..." @@ -324,7 +321,7 @@ def _get_event_platform_spans(self, query_filter, limit): request_data = { "list": { - "search": {"query": f"env:system-tests {query_filter}",}, + "search": {"query": f"env:system-tests {query_filter}"}, "indexes": ["trace-search"], "time": { # 30 min of window should be plenty diff --git a/utils/interfaces/_core.py b/utils/interfaces/_core.py index 973544837cb..fdb47919fa9 100644 --- a/utils/interfaces/_core.py +++ b/utils/interfaces/_core.py @@ -2,18 +2,19 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -""" This file contains base class used to validate interfaces """ +"""Contains base class used to validate interfaces""" import json from os import listdir from os.path import isfile, join +from pathlib import Path import re +import shutil import threading import time import pytest -from utils._context.core import context from utils.tools import logger from utils.interfaces._schemas_validators import SchemaValidator, SchemaError @@ -24,13 +25,18 @@ class InterfaceValidator: One instance of this list handle only one interface """ + replay: bool + """ True if the process is in replay mode """ + + log_folder: str + """ Folder where interfaces' logs are stored """ + def __init__(self, name): self.name = name - self.replay = False - - def configure(self, replay): + def configure(self, host_log_folder, replay): self.replay = replay + self.log_folder = f"{host_log_folder}/interfaces/{self.name}" def __repr__(self): return f"{self.__class__.__name__}('{self.name}')" @@ -40,7 +46,7 @@ def __str__(self): class ProxyBasedInterfaceValidator(InterfaceValidator): - """ Interfaces based on proxy container """ + """Interfaces based on proxy container""" def __init__(self, name): super().__init__(name) @@ -53,19 +59,22 @@ def __init__(self, name): self._ingested_files = set() self._schema_errors = None - @property - def _log_folder(self): - return f"{context.scenario.host_log_folder}/interfaces/{self.name}" + def configure(self, host_log_folder, replay): + super().configure(host_log_folder, replay) - def ingest_file(self, src_path): + if not replay: + shutil.rmtree(self.log_folder, ignore_errors=True) + Path(self.log_folder).mkdir(parents=True, exist_ok=True) + Path(self.log_folder + "/files").mkdir(parents=True, exist_ok=True) + def ingest_file(self, src_path): with self._lock: if src_path in self._ingested_files: return logger.debug(f"Ingesting {src_path}") - with open(src_path, "r", encoding="utf-8") as f: + with open(src_path, encoding="utf-8") as f: try: data = json.load(f) except json.decoder.JSONDecodeError: @@ -85,7 +94,7 @@ def wait(self, timeout): time.sleep(timeout) def check_deserialization_errors(self): - """ Verify that all proxy deserialization are successful """ + """Verify that all proxy deserialization are successful""" for data in self._data_list: filename = data["log_filename"] @@ -98,12 +107,10 @@ def check_deserialization_errors(self): pytest.exit(reason=f"Unexpected error while deserialize {filename}:\n {traceback}", returncode=1) def load_data_from_logs(self): - - for filename in sorted(listdir(self._log_folder)): - file_path = join(self._log_folder, filename) + for filename in sorted(listdir(self.log_folder)): + file_path = join(self.log_folder, filename) if isfile(file_path): - - with open(file_path, "r", encoding="utf-8") as f: + with open(file_path, encoding="utf-8") as f: data = json.load(f) self._append_data(data) @@ -113,7 +120,6 @@ def _append_data(self, data): self._data_list.append(data) def get_data(self, path_filters=None): - if path_filters is not None: if isinstance(path_filters, str): path_filters = [path_filters] @@ -121,12 +127,12 @@ def get_data(self, path_filters=None): path_filters = [re.compile(path) for path in path_filters] for data in self._data_list: - if path_filters is not None and all((path.fullmatch(data["path"]) is None for path in path_filters)): + if path_filters is not None and all(path.fullmatch(data["path"]) is None for path in path_filters): continue yield data - def validate(self, validator, path_filters=None, success_by_default=False): + def validate(self, validator, path_filters=None, *, success_by_default=False): for data in self.get_data(path_filters=path_filters): try: if validator(data) is True: @@ -146,7 +152,6 @@ def validate(self, validator, path_filters=None, success_by_default=False): raise ValueError("Test has not been validated by any data") def wait_for(self, wait_for_function, timeout): - if self.replay: return @@ -154,6 +159,7 @@ def wait_for(self, wait_for_function, timeout): with self._lock: for data in self._data_list: if wait_for_function(data): + logger.info(f"wait for {wait_for_function} finished in success with existing data") return # then set the lock, and wait for append_data to release it @@ -201,6 +207,33 @@ def assert_schema_points(self, excluded_points=None): assert not has_error, f"Schema validation failed for {self.name}" + def assert_request_header(self, path, header_name_pattern: str, header_value_pattern: str) -> None: + """Assert that a header, and its value are present in all requests for a given path + header_name_pattern: a regular expression to match the header name (lower case) + header_value_pattern: a regular expression to match the header value + """ + + data_found = False + + for data in self.get_data(path): + data_found = True + + found = False + + for header, value in data["request"]["headers"]: + if re.fullmatch(header_name_pattern, header.lower()): + if not re.fullmatch(header_value_pattern, value): + logger.error(f"Header {header} found in {data['log_filename']}, but value is {value}") + else: + found = True + continue + + if not found: + raise ValueError(f"{header_name_pattern} not found (or incorrect) in {data['log_filename']}") + + if not data_found: + raise ValueError(f"No data found for {path}") + class ValidationError(Exception): def __init__(self, *args: object, extra_info=None) -> None: diff --git a/utils/interfaces/_library/_utils.py b/utils/interfaces/_library/_utils.py index 2796ce47c45..d2b1abeb41c 100644 --- a/utils/interfaces/_library/_utils.py +++ b/utils/interfaces/_library/_utils.py @@ -26,6 +26,4 @@ def get_trace_request_path(root_span): if url is None: return None - path = urlparse(url).path - - return path + return urlparse(url).path diff --git a/utils/interfaces/_library/appsec.py b/utils/interfaces/_library/appsec.py index 66e46d2c578..ad6dd78dec3 100644 --- a/utils/interfaces/_library/appsec.py +++ b/utils/interfaces/_library/appsec.py @@ -2,7 +2,7 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -""" AppSec validators """ +"""AppSec validators""" from collections import Counter from utils.interfaces._library.appsec_data import rule_id_to_type @@ -13,7 +13,6 @@ class _WafAttack: def __init__( self, rule=None, pattern=None, patterns=None, value=None, address=None, key_path=None, span_validator=None ): - # rule can be a rule id, or a rule type if rule is None: self.rule_id = None @@ -112,11 +111,11 @@ def validate(self, span, appsec_data): elif self.address and self.key_path and (self.address, self.key_path) not in full_addresses: logger.info(f"saw {full_addresses}, expecting {(self.address, self.key_path)}") - elif self.span_validator and not self.span_validator(span, appsec_data): - return False # validator should output the reason for the failure - else: - return True + # validator should output the reason for the failure + return not (self.span_validator and not self.span_validator(span, appsec_data)) + + return None def validate_legacy(self, event): event_version = event.get("event_version", "0.1.0") @@ -152,19 +151,21 @@ def validate_legacy(self, event): else: return True + return False + class _ReportedHeader: def __init__(self, header_name): self.header_name = header_name.lower() def validate_legacy(self, event): - headers = [n.lower() for n in event["context"]["http"]["request"]["headers"].keys()] + headers = [n.lower() for n in event["context"]["http"]["request"]["headers"]] assert self.header_name in headers, f"header {self.header_name} not reported" return True - def validate(self, span, appsec_data): - headers = [n.lower() for n in span["meta"].keys() if n.startswith("http.request.headers.")] + def validate(self, span, appsec_data): # noqa: ARG002 + headers = [n.lower() for n in span["meta"] if n.startswith("http.request.headers.")] assert f"http.request.headers.{self.header_name}" in headers, f"header {self.header_name} not reported" return True diff --git a/utils/interfaces/_library/core.py b/utils/interfaces/_library/core.py index d75976f3898..560f0bb8479 100644 --- a/utils/interfaces/_library/core.py +++ b/utils/interfaces/_library/core.py @@ -2,11 +2,13 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. +import base64 import copy import json import threading from utils.tools import logger, get_rid_from_user_agent, get_rid_from_span, get_rid_from_request +from utils.dd_constants import RemoteConfigApplyState, Capabilities from utils.interfaces._core import ProxyBasedInterfaceValidator from utils.interfaces._library._utils import get_trace_request_path from utils.interfaces._library.appsec import _WafAttack, _ReportedHeader @@ -32,7 +34,7 @@ def ingest_file(self, src_path): ################################################################ def wait_for_remote_config_request(self, timeout=30): - """ Used in setup functions, wait for a request oremote config endpoint with a non-empty client_config """ + """Used in setup functions, wait for a request oremote config endpoint with a non-empty client_config""" def wait_function(data): if data["path"] == "/v0.7/config": @@ -54,6 +56,9 @@ def get_traces(self, request=None): for data in self.get_data(path_filters=paths): traces = data["request"]["content"] + if not traces: # may be none + continue + for trace in traces: if rid is None: yield data, trace @@ -63,7 +68,7 @@ def get_traces(self, request=None): yield data, trace break - def get_spans(self, request=None, full_trace=False): + def get_spans(self, request=None, *, full_trace=False): """Iterate over all spans reported by the tracer to the agent. If request is not None and full_trace is False, only span trigered by that request will be @@ -89,17 +94,15 @@ def get_root_spans(self, request=None): if span.get("parent_id") in (0, None): yield data, span - def get_appsec_events(self, request=None, full_trace=False): + def get_appsec_events(self, request=None, *, full_trace=False): for data, trace, span in self.get_spans(request=request, full_trace=full_trace): if "appsec" in span.get("meta_struct", {}): - if request: # do not spam log if all data are sent to the validator logger.debug(f"Try to find relevant appsec data in {data['log_filename']}; span #{span['span_id']}") appsec_data = span["meta_struct"]["appsec"] yield data, trace, span, appsec_data elif "_dd.appsec.json" in span.get("meta", {}): - if request: # do not spam log if all data are sent to the validator logger.debug(f"Try to find relevant appsec data in {data['log_filename']}; span #{span['span_id']}") @@ -115,7 +118,6 @@ def get_legacy_appsec_events(self, request=None): events = data["request"]["content"]["events"] for event in events: if "trace" in event["context"] and "span" in event["context"]: - if rid is None: yield data, event else: @@ -135,14 +137,13 @@ def get_legacy_appsec_events(self, request=None): for user_agent in user_agents: if get_rid_from_user_agent(user_agent) == rid: - if request: # do not spam log if all data are sent to the validator logger.debug(f"Try to find relevant appsec data in {data['log_filename']}") yield data, event break - def get_telemetry_data(self, flatten_message_batches=True): + def get_telemetry_data(self, *, flatten_message_batches=True): all_data = self.get_data(path_filters="/telemetry/proxy/api/v2/apmtelemetry") if not flatten_message_batches: yield from all_data @@ -160,7 +161,7 @@ def get_telemetry_data(self, flatten_message_batches=True): yield data def get_telemetry_metric_series(self, namespace, metric): - relevantSeries = [] + relevant_series = [] for data in self.get_telemetry_data(): content = data["request"]["content"] if content.get("request_type") != "generate-metrics": @@ -173,12 +174,12 @@ def get_telemetry_metric_series(self, namespace, metric): # Inject here the computed namespace considering the fallback. This simplifies later assertions. series["_computed_namespace"] = computed_namespace if computed_namespace == namespace and series["metric"] == metric: - relevantSeries.append(series) - return relevantSeries + relevant_series.append(series) + return relevant_series ############################################################ - def validate_telemetry(self, validator, success_by_default=False): + def validate_telemetry(self, validator, *, success_by_default=False): def validator_skip_onboarding_event(data): if data["request"]["content"].get("request_type") == "apm-onboarding-event": return None @@ -191,9 +192,8 @@ def validator_skip_onboarding_event(data): ) def validate_appsec( - self, request=None, validator=None, success_by_default=False, legacy_validator=None, full_trace=False + self, request=None, validator=None, *, success_by_default=False, legacy_validator=None, full_trace=False ): - if validator: for _, _, span, appsec_data in self.get_appsec_events(request=request, full_trace=full_trace): if validator(span, appsec_data): @@ -287,6 +287,7 @@ def assert_waf_attack( address=None, patterns=None, key_path=None, + *, full_trace=False, span_validator=None, ): @@ -319,13 +320,13 @@ def add_appsec_reported_header(self, request, header_name): validator = _ReportedHeader(header_name) self.validate_appsec( - request, validator=validator.validate, legacy_validator=validator.validate_legacy, success_by_default=False, + request, validator=validator.validate, legacy_validator=validator.validate_legacy, success_by_default=False ) - def add_traces_validation(self, validator, success_by_default=False): + def add_traces_validation(self, validator, *, success_by_default=False): self.validate(validator=validator, success_by_default=success_by_default, path_filters=r"/v0\.[1-9]+/traces") - def validate_traces(self, request=None, validator=None, success_by_default=False): + def validate_traces(self, request=None, validator=None, *, success_by_default=False): for _, trace in self.get_traces(request=request): if validator(trace): return @@ -333,8 +334,8 @@ def validate_traces(self, request=None, validator=None, success_by_default=False if not success_by_default: raise ValueError("No span validates this test") - def validate_spans(self, request=None, validator=None, success_by_default=False): - for _, _, span in self.get_spans(request=request): + def validate_spans(self, request=None, validator=None, *, success_by_default=False, full_trace: bool = False): + for _, _, span in self.get_spans(request=request, full_trace=full_trace): try: if validator(span): return @@ -345,10 +346,10 @@ def validate_spans(self, request=None, validator=None, success_by_default=False) if not success_by_default: raise ValueError("No span validates this test") - def add_span_tag_validation(self, request=None, tags=None, value_as_regular_expression=False): + def add_span_tag_validation(self, request=None, tags=None, *, value_as_regular_expression=False, full_trace=False): validator = _SpanTagValidator(tags=tags, value_as_regular_expression=value_as_regular_expression) success = False - for _, _, span in self.get_spans(request=request): + for _, _, span in self.get_spans(request=request, full_trace=full_trace): success = success or validator(span) if not success: @@ -367,6 +368,9 @@ def assert_no_skipped_seq_ids(self): def get_profiling_data(self): yield from self.get_data(path_filters="/profiling/v1/input") + def validate_profiling(self, validator, *, success_by_default=False): + self.validate(validator, path_filters="/profiling/v1/input", success_by_default=success_by_default) + def assert_trace_exists(self, request, span_type=None): for _, _, span in self.get_spans(request=request): if span_type is None or span.get("type") == span_type: @@ -374,9 +378,71 @@ def assert_trace_exists(self, request, span_type=None): raise ValueError(f"No trace has been found for request {get_rid_from_request(request)}") - def validate_remote_configuration(self, validator, success_by_default=False): + def validate_remote_configuration(self, validator, *, success_by_default=False): self.validate(validator, success_by_default=success_by_default, path_filters=r"/v\d+.\d+/config") + def assert_rc_apply_state(self, product: str, config_id: str, apply_state: RemoteConfigApplyState) -> None: + """Check that all config_id/product have the expected apply_state returned by the library + Very simplified version of the assert_rc_targets_version_states + + """ + found = False + for data in self.get_data(path_filters="/v0.7/config"): + config_states = data["request"]["content"]["client"]["state"].get("config_states", []) + + for config_state in config_states: + if config_state["id"] == config_id and config_state["product"] == product: + logger.debug(f"In {data['log_filename']}: found {config_state}") + assert config_state["apply_state"] == apply_state.value + found = True + + assert found, f"Nothing has been found for {config_id}/{product}" + + def assert_rc_capability(self, capability: Capabilities): + found = False + for data in self.get_data(path_filters="/v0.7/config"): + capabilities = data["request"]["content"]["client"]["capabilities"] + if isinstance(capabilities, list): + decoded_capabilities = bytes(capabilities) + # base64-encoded string: + else: + decoded_capabilities = base64.b64decode(capabilities) + int_capabilities = int.from_bytes(decoded_capabilities, byteorder="big") + if (int_capabilities >> capability & 1) == 1: + found = True + assert found, f"Capability {capability.name} not found" + + def assert_rc_targets_version_states(self, targets_version: int, config_states: list) -> None: + """Check that for a given targets_version, the config states is the one expected + EXPERIMENTAL (is it the good testing API ?) + """ + found = False + for data in self.get_data(path_filters="/v0.7/config"): + state = data["request"]["content"]["client"]["state"] + + if state["targets_version"] != targets_version: + continue + + logger.debug(f"In {data['log_filename']}: found targets_version {targets_version}") + + assert not state.get("has_error", False), f"State error found: {state.get('error')}" + + observed_config_states = state.get("config_states", []) + logger.debug(f"Observed: {observed_config_states}") + logger.debug(f"expected: {config_states}") + + # apply_error is optional, and can be none or empty string. + # remove it in that situation to simplify the comparison + observed_config_states = copy.deepcopy(observed_config_states) # copy to not mess up futur checks + for observed_config_state in observed_config_states: + if "apply_error" in observed_config_state and observed_config_state["apply_error"] in (None, ""): + del observed_config_state["apply_error"] + + assert config_states == observed_config_states + found = True + + assert found, f"Nothing has been found for targets_version {targets_version}" + def assert_rasp_attack(self, request, rule: str, parameters=None): def validator(_, appsec_data): assert "triggers" in appsec_data, "'triggers' not found in '_dd.appsec.json'" @@ -410,10 +476,14 @@ def validator(_, appsec_data): obtained_param = obtained_parameters[name] - assert obtained_param["address"] == address, f"incorrect address for '{name}', expected '{address}'" + assert ( + obtained_param["address"] == address + ), f"incorrect address for '{name}', expected '{address}, found '{obtained_param['address']}'" if value is not None: - assert obtained_param["value"] == value, f"incorrect value for '{name}', expected '{value}'" + assert ( + obtained_param["value"] == value + ), f"incorrect value for '{name}', expected '{value}', found '{obtained_param['value']}'" if key_path is not None: assert ( diff --git a/utils/interfaces/_library/miscs.py b/utils/interfaces/_library/miscs.py index 9e5e2e80574..9927b558e9d 100644 --- a/utils/interfaces/_library/miscs.py +++ b/utils/interfaces/_library/miscs.py @@ -2,7 +2,7 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -""" Misc validations """ +"""Misc validations""" import re @@ -17,18 +17,19 @@ def __init__(self, tags, value_as_regular_expression): self.value_as_regular_expression = value_as_regular_expression def __call__(self, span): - for tagKey in self.tags: - if tagKey not in span["meta"]: - raise ValueError(f"{tagKey} tag not found in span's meta") + for tag_key in self.tags: + if tag_key not in span["meta"]: + raise ValueError(f"{tag_key} tag not found in span's meta") - expectValue = self.tags[tagKey] - actualValue = span["meta"][tagKey] + expect_value = self.tags[tag_key] + actual_value = span["meta"][tag_key] if self.value_as_regular_expression: - if not re.compile(expectValue).fullmatch(actualValue): - raise ValueError(f'{tagKey} tag value is "{actualValue}", and should match regex "{expectValue}"') - else: - if expectValue != actualValue: - raise ValueError(f'{tagKey} tag in span\'s meta should be "{expectValue}", not "{actualValue}"') + if not re.compile(expect_value).fullmatch(actual_value): + raise ValueError( + f'{tag_key} tag value is "{actual_value}", and should match regex "{expect_value}"' + ) + elif expect_value != actual_value: + raise ValueError(f'{tag_key} tag in span\'s meta should be "{expect_value}", not "{actual_value}"') return True diff --git a/utils/interfaces/_library/telemetry.py b/utils/interfaces/_library/telemetry.py index 4deae855fb8..84c2019a97b 100644 --- a/utils/interfaces/_library/telemetry.py +++ b/utils/interfaces/_library/telemetry.py @@ -18,12 +18,11 @@ def __call__(self, data): if seq_id > self.max_seq_id: self.max_seq_id = seq_id self.received_max_time = now - else: - if self.received_max_time is not None and (now - self.received_max_time) > self.MAX_OUT_OF_ORDER_LAG: - raise ValueError( - f"Received message with seq_id {seq_id} to far more than" - f"100ms after message with seq_id {self.max_seq_id}" - ) + elif self.received_max_time is not None and (now - self.received_max_time) > self.MAX_OUT_OF_ORDER_LAG: + raise ValueError( + f"Received message with seq_id {seq_id} to far more than" + f"100ms after message with seq_id {self.max_seq_id}" + ) class _NoSkippedSeqId: diff --git a/utils/interfaces/_logs.py b/utils/interfaces/_logs.py index fb19d5126bf..cff94e38db8 100644 --- a/utils/interfaces/_logs.py +++ b/utils/interfaces/_logs.py @@ -26,7 +26,7 @@ def __init__(self, name, new_log_line_pattern=None): self._data_list = [] def _get_files(self): - raise NotImplementedError() + raise NotImplementedError def _clean_line(self, line): return line @@ -49,9 +49,10 @@ def _read(self): logger.info(f"For {self}, reading {filename}") log_count = 0 try: - with open(filename, "r", encoding="utf-8") as f: + with open(filename, encoding="utf-8") as f: buffer = [] - for line in f: + for raw_line in f: + line = raw_line if line.endswith("\n"): line = line[:-1] # remove tailing \n line = self._clean_line(line) @@ -77,7 +78,6 @@ def load_data(self): logger.debug(f"Load data for log interface {self.name}") for log_line in self._read(): - parsed = {} for parser in self._parsers: m = parser.match(log_line) @@ -94,8 +94,7 @@ def load_data(self): def get_data(self): yield from self._data_list - def validate(self, validator, success_by_default=False): - + def validate(self, validator, *, success_by_default=False): for data in self.get_data(): try: if validator(data) is True: @@ -131,9 +130,10 @@ def _get_files(self): class _LibraryStdout(_StdoutLogsInterfaceValidator): def __init__(self): super().__init__("weblog") + self.library = None - def configure(self, replay): - super().configure(replay) + def init_patterns(self, library): + self.library = library p = "(?P<{}>{})".format self._skipped_patterns += [ @@ -141,7 +141,7 @@ def configure(self, replay): re.compile(r"systemtests_weblog_1 exited with code \d+"), ] - if context.library == "java": + if library == "java": self._skipped_patterns += [ re.compile(r"^[ /\\_,''.()=`|]*$"), # Java Spring ASCII art re.compile(r"^ +:: Spring Boot :: +\(v\d+.\d+.\d+(-SNAPSHOT)?\)$"), @@ -160,9 +160,9 @@ def configure(self, replay): klass = p("klass", r"[\w\.$\[\]/]+") self._parsers.append(re.compile(rf"^{timestamp} +{level} \d -+ \[ *{thread}\] +{klass} *: *{message}")) - elif context.library == "dotnet": + elif library == "dotnet": self._new_log_line_pattern = re.compile(r"^\s*(info|debug|error)") - elif context.library == "php": + elif library == "php": self._skipped_patterns += [ re.compile(r"^(?!\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}\]\[[a-z]+\]\[\d+\])"), ] @@ -183,7 +183,7 @@ def _clean_line(self, line): return line def _get_standardized_level(self, level): - if context.library == "php": + if self.library == "php": return level.upper() return super()._get_standardized_level(level) @@ -265,20 +265,22 @@ def check(self, data): if "message" in data and self.pattern.search(data["message"]): for key, extra_pattern in self.extra_conditions.items(): if key not in data: - logger.info(f"For {self}, {repr(self.pattern.pattern)} was found, but [{key}] field is missing") + logger.info(f"For {self}, {self.pattern.pattern!r} was found, but [{key}] field is missing") logger.info(f"-> Log line is {data['message']}") - return + return None if not extra_pattern.search(data[key]): logger.info( - f"For {self}, {repr(self.pattern.pattern)} was found, but condition on [{key}] failed: " + f"For {self}, {self.pattern.pattern!r} was found, but condition on [{key}] failed: " f"'{extra_pattern.pattern}' != '{data[key]}'" ) - return + return None logger.debug(f"For {self}, found {data['message']}") return True + return None + class _LogAbsence: def __init__(self, pattern, allowed_patterns=None): @@ -288,7 +290,6 @@ def __init__(self, pattern, allowed_patterns=None): def check(self, data): if self.pattern.search(data["raw"]): - for pattern in self.allowed_patterns: if pattern.search(data["raw"]): return @@ -306,11 +307,11 @@ def test_main(self): context.scenario = scenarios.default i = _PostgresStdout() - i.configure(True) + i.configure(scenarios.default.host_log_folder, replay=True) i.load_data() for item in i.get_data(): - print(item) + print(item) # noqa: T201 if __name__ == "__main__": diff --git a/utils/interfaces/_open_telemetry.py b/utils/interfaces/_open_telemetry.py index 9e69fbe4d96..de3eeef8cd7 100644 --- a/utils/interfaces/_open_telemetry.py +++ b/utils/interfaces/_open_telemetry.py @@ -2,9 +2,7 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -""" -This files will validate data flow between agent and backend -""" +"""Validate data flow between agent and backend""" import threading @@ -13,7 +11,7 @@ class OpenTelemetryInterfaceValidator(ProxyBasedInterfaceValidator): - """ Validated communication between open telemetry and datadog backend""" + """Validated communication between open telemetry and datadog backend""" def __init__(self): super().__init__("open_telemetry") diff --git a/utils/interfaces/_schemas_validators.py b/utils/interfaces/_schemas_validators.py index 9f226ca25ae..3f9055647f8 100644 --- a/utils/interfaces/_schemas_validators.py +++ b/utils/interfaces/_schemas_validators.py @@ -2,13 +2,13 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. -""" -Usage: - PYTHONPATH=. python utils/interfaces/_schemas_validators.py +"""Usage: +PYTHONPATH=. python utils/interfaces/_schemas_validators.py """ from dataclasses import dataclass import os +from pathlib import Path import json import re import functools @@ -37,9 +37,9 @@ def _get_schemas_filenames(): yield os.path.join(root, f) -@functools.lru_cache() +@functools.lru_cache def _get_schemas_store(): - """returns a dict with all defined schemas""" + """Returns a dict with all defined schemas""" store = {} @@ -57,7 +57,7 @@ def _get_schemas_store(): return store -@functools.lru_cache() +@functools.lru_cache def _get_schema_validator(schema_id): store = _get_schemas_store() @@ -78,10 +78,7 @@ class SchemaError: @property def message(self): - return ( - f"{self.error.message} on instance {self.error.json_path} in {self.endpoint}. Please check " - + self.data["log_filename"] - ) + return f"{self.data['log_filename']}: {self.error.message} on instance {self.error.json_path}" @property def data_path(self): @@ -108,7 +105,7 @@ def get_errors(self, data) -> list[SchemaError]: return [] return [ - SchemaError(interface_name=self.interface, endpoint=path, error=error, data=data,) + SchemaError(interface_name=self.interface, endpoint=path, error=error, data=data) for error in validator.iter_errors(data["request"]["content"]) ] @@ -116,7 +113,7 @@ def get_errors(self, data) -> list[SchemaError]: def _main(): for interface in ("agent", "library"): validator = SchemaValidator(interface) - folders = [folder for folder in os.listdir(".") if os.path.isdir(folder) and folder.startswith("logs")] + folders = [folder for folder in os.listdir(".") if Path(folder).is_dir() and folder.startswith("logs")] for folder in folders: path = f"{folder}/interfaces/{interface}" @@ -129,7 +126,7 @@ def _main(): if "request" in data and data["request"]["length"] != 0: for error in validator.get_errors(data): - print(error.message) + print(error.message) # noqa: T201 if __name__ == "__main__": diff --git a/utils/interfaces/_test_agent.py b/utils/interfaces/_test_agent.py new file mode 100644 index 00000000000..d4c8bdd983c --- /dev/null +++ b/utils/interfaces/_test_agent.py @@ -0,0 +1,106 @@ +import pathlib +import threading +import json +from utils.interfaces._core import InterfaceValidator +from utils.tools import logger, get_rid_from_request + + +class _TestAgentInterfaceValidator(InterfaceValidator): + def __init__(self): + super().__init__("test_agent") + self.ready = threading.Event() + self._data_traces_list = [] + self._data_telemetry_list = [] + + def collect_data(self, interface_folder, agent_host="localhost", agent_port=8126): + import ddapm_test_agent.client as agent_client + + logger.debug("Collecting data from test agent") + client = agent_client.TestAgentClient(base_url=f"http://{agent_host}:{agent_port}") + self._data_traces_list = client.traces(clear=False) + if self._data_traces_list: + pathlib.Path(f"{interface_folder}/00_traces.json").write_text( + json.dumps(self._data_traces_list, indent=2), encoding="utf-8" + ) + + self._data_telemetry_list = client.telemetry(clear=False) + if self._data_telemetry_list: + pathlib.Path(f"{interface_folder}/00_telemetry.json").write_text( + json.dumps(self._data_telemetry_list, indent=2), encoding="utf-8" + ) + + def get_traces(self, request=None): + rid = get_rid_from_request(request) + if not rid: + raise ValueError("Request ID not found") + logger.debug(f"Try to find traces related to request {rid}") + + for data in self._data_traces_list: + for data_received in data: + if "trace_id" in data_received: + if "http.useragent" in data_received["meta"]: + if rid in data_received["meta"]["http.useragent"]: + return data_received + return None + + def get_telemetry_for_runtime(self, runtime_id): + logger.debug(f"Try to find telemetry data related to runtime-id {runtime_id}") + assert runtime_id is not None, "Runtime ID not found" + telemetry_msgs = [] + for data_received in self._data_telemetry_list: + if data_received["runtime_id"] == runtime_id: + telemetry_msgs.append(data_received) + + return telemetry_msgs + + def get_crashlog_for_runtime(self, runtime_id): + logger.debug(f"Try to find a crashlog related to runtime-id {runtime_id}") + assert runtime_id is not None, "Runtime ID not found" + return [log for log in self.get_telemetry_logs() if log["runtime_id"] == runtime_id] + + def get_telemetry_for_autoinject(self): + logger.debug("Try to find telemetry data related to autoinject") + injection_metrics = [] + injection_metrics += [ + series + for t in self._data_telemetry_list + if t["request_type"] == "generate-metrics" + for series in t["payload"]["series"] + if str(series["metric"]).startswith("inject.") + ] + return injection_metrics + + def get_telemetry_for_autoinject_library_entrypoint(self): + logger.debug("Try to find telemetry data related to the library entrypoint") + injection_metrics = [] + injection_metrics += [ + series + for t in self._data_telemetry_list + if t["request_type"] == "generate-metrics" + for series in t["payload"]["series"] + if str(series["metric"]).startswith("library_entrypoint.") + ] + return injection_metrics + + def get_telemetry_logs(self): + logger.debug("Try to find telemetry data related to logs") + return [t for t in self._data_telemetry_list if t["request_type"] == "logs"] + + def get_crash_reports(self): + logger.debug("Try to find telemetry data related to crash reports") + crash_reports = [] + + for t in self.get_telemetry_logs(): + payload = t["payload"] + + # If payload is a list, iterate through its items + if isinstance(payload, list): + crash_reports.extend( + p for p in payload if "signame" in p.get("tags", "") or "signum" in p.get("tags", "") + ) + # If payload is a single object, check it directly + elif isinstance(payload, dict): + if "signame" in payload.get("tags", "") or "signum" in payload.get("tags", ""): + crash_reports.append(payload) + + return crash_reports diff --git a/utils/interfaces/schemas/Dockerfile b/utils/interfaces/schemas/Dockerfile index 936bef94662..2c297905e63 100644 --- a/utils/interfaces/schemas/Dockerfile +++ b/utils/interfaces/schemas/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9 +FROM python:3.12 COPY ./requirements.txt /app/requirements.txt WORKDIR /app diff --git a/utils/interfaces/schemas/agent/api/v0.2/stats-request.json b/utils/interfaces/schemas/agent/api/v0.2/stats-request.json index 8619b50321c..702b689d0fb 100644 --- a/utils/interfaces/schemas/agent/api/v0.2/stats-request.json +++ b/utils/interfaces/schemas/agent/api/v0.2/stats-request.json @@ -1,4 +1,41 @@ { - "$id": "/agent/api/v0.2/stats-request.json", - "type": "object" - } \ No newline at end of file + "$id": "/agent/api/v0.2/stats-request.json", + "type": "object", + "properties": { + "Stats": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Stats": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Start": { "type": "integer" }, + "Duration": { "type": "integer" }, + "Stats": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Service": { "type": "string" }, + "Name": { "type": "string" }, + "Resource": { "type": "string" } + }, + "required": ["Service", "Name", "Resource"] + } + } + }, + "required": ["Start", "Duration", "Stats"] + } + } + }, + "required": ["Stats"] + } + } + }, + "required": [ + "Stats" + ] +} \ No newline at end of file diff --git a/utils/interfaces/schemas/agent/api/v2/debugger-request.json b/utils/interfaces/schemas/agent/api/v2/debugger-request.json index 5cd298acbf4..4d8177052c9 100644 --- a/utils/interfaces/schemas/agent/api/v2/debugger-request.json +++ b/utils/interfaces/schemas/agent/api/v2/debugger-request.json @@ -1,3 +1,13 @@ { - "$id": "/agent/api/v2/debugger-request.json" + "$id": "/agent/api/v2/debugger-request.json", + "type": "array", + "items": { + "type": "object", + "properties":{ + "content": { + "type": "array" + } + }, + "required": ["content"] + } } diff --git a/utils/interfaces/schemas/library/debugger/v1/diagnostics-request.json b/utils/interfaces/schemas/library/debugger/v1/diagnostics-request.json index 9f76ae7b7af..c870a24e7da 100644 --- a/utils/interfaces/schemas/library/debugger/v1/diagnostics-request.json +++ b/utils/interfaces/schemas/library/debugger/v1/diagnostics-request.json @@ -39,14 +39,12 @@ "diagnostics" ] }, - "message": { "type": "string" }, "service": { "type": "string" }, "timestamp": { "type": "number" } }, "required": [ "ddsource", "debugger", - "message", "service" ] } diff --git a/utils/interfaces/schemas/library/v0.4/misc/trace-item.json b/utils/interfaces/schemas/library/v0.4/misc/trace-item.json index 891205878d2..ef1ae7bddd1 100644 --- a/utils/interfaces/schemas/library/v0.4/misc/trace-item.json +++ b/utils/interfaces/schemas/library/v0.4/misc/trace-item.json @@ -22,9 +22,25 @@ "span_id": { "type": "integer" }, "trace_id": { "type": "integer" }, "parent_id": { "anyOf": [{ "type": "integer" }, { "type": "null" }] }, - "error": { "type": "integer" } + "error": { "type": "integer" }, + "span_links": { + "type": "array", + "items": { + "type": "object", + "required": ["trace_id", "span_id"], + "properties": { + "trace_id": { "type": "integer" }, + "span_id": { "type": "integer" }, + "attributes": { + "type": "object", + "patternProperties": { + ".*": { "type": "string" } + } + } + } + } + } }, - "required": ["name"] } } diff --git a/utils/interfaces/schemas/serve_doc.py b/utils/interfaces/schemas/serve_doc.py index 0268b210868..de520fcd4b5 100644 --- a/utils/interfaces/schemas/serve_doc.py +++ b/utils/interfaces/schemas/serve_doc.py @@ -3,17 +3,17 @@ # Copyright 2021 Datadog, Inc. import os -import json +from pathlib import Path -from flask import Flask, send_from_directory, request, render_template -from utils.interfaces._schemas_validators import _get_schemas_store, _get_schemas_filenames -from json_schema_for_humans.generate import generate_from_schema, generate_from_filename +from flask import Flask, render_template +from utils.interfaces._schemas_validators import _get_schemas_store +from json_schema_for_humans.generate import generate_from_schema from json_schema_for_humans.generation_configuration import GenerationConfiguration import json_schema_for_humans static_folder = os.path.join(json_schema_for_humans.__path__[0], "templates/js") -template_folder = os.path.join(os.getcwd(), "utils/interfaces/schemas") +template_folder = os.path.join(str(Path.cwd()), "utils/interfaces/schemas") app = Flask(__name__, static_url_path="/static", static_folder=static_folder, template_folder=template_folder) @@ -23,15 +23,14 @@ @app.route("/", methods=["GET"]) def default(): - data = {"schemas": []} - for id, schema in store.items(): + for schema_id, schema in store.items(): # skip some schemas - if not id.endswith("request.json") and not "title" in schema: + if not schema_id.endswith("request.json") and "title" not in schema: continue - doc_path = id.replace(".json", ".html") + doc_path = schema_id.replace(".json", ".html") # doc_path = doc_path[len("utils/interfaces/schemas"):] # filename = filename[len("utils/interfaces/schemas"):] @@ -46,10 +45,8 @@ def documentation(path): doc = generate_from_schema(path, store, config=store_config) doc = doc.replace("schema_doc.css", "/static/schema_doc.css") - doc = doc.replace("schema_doc.min.js", "/static/schema_doc.min.js") - - return doc + return doc.replace("schema_doc.min.js", "/static/schema_doc.min.js") if __name__ == "__main__": - app.run(port=8080, debug=True) + app.run(port=8080, debug=True) # noqa: S201 diff --git a/utils/k8s_lib_injection/__init__.py b/utils/k8s_lib_injection/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/k8s_lib_injection/k8s_command_utils.py b/utils/k8s_lib_injection/k8s_command_utils.py index c56d7b49fb0..6a36f8269b4 100644 --- a/utils/k8s_lib_injection/k8s_command_utils.py +++ b/utils/k8s_lib_injection/k8s_command_utils.py @@ -1,25 +1,32 @@ -import subprocess, datetime, os, time, signal +import subprocess, datetime, os, time, signal, shlex from utils.tools import logger from utils import context from utils.k8s_lib_injection.k8s_sync_kubectl import KubectlLock from retry import retry -def execute_command(command, timeout=None, logfile=None): - """call shell-command and either return its output or kill it - if it doesn't normally exit within timeout seconds and return None""" +def execute_command(command, timeout=None, logfile=None, subprocess_env=None): + """Call shell-command and either return its output or kill it + if it doesn't normally exit within timeout seconds and return None + """ applied_timeout = 90 if timeout is not None: applied_timeout = timeout - logger.debug(f"Launching Command: {command} ") + logger.debug(f"Launching Command: {_clean_secrets(command)} ") command_out_redirect = subprocess.PIPE if logfile: command_out_redirect = open(logfile, "w") + + if not subprocess_env: + subprocess_env = os.environ.copy() + output = "" try: start = datetime.datetime.now() - process = subprocess.Popen(command.split(), stdout=command_out_redirect, stderr=command_out_redirect) + process = subprocess.Popen( + shlex.split(command), stdout=command_out_redirect, stderr=command_out_redirect, env=subprocess_env + ) while process.poll() is None: time.sleep(0.1) @@ -32,26 +39,40 @@ def execute_command(command, timeout=None, logfile=None): return None else: # if we specify a timeout, we raise an exception - raise Exception(f"Command: {command} timed out after {applied_timeout} seconds") - + raise Exception(f"Command: {_clean_secrets(command)} timed out after {applied_timeout} seconds") if not logfile: output = process.stdout.read() - logger.debug(f"Command: {command} \n {output}") + output = str(output, "utf-8") + logger.debug(f"Command: {_clean_secrets(command)} \n {_clean_secrets(output)}") if process.returncode != 0: output_error = process.stderr.read() - logger.debug(f"Command: {command} \n {output_error}") - raise Exception(f"Error executing command: {command} \n {output}") + logger.debug(f"Command: {_clean_secrets(command)} \n {_clean_secrets(output_error)}") + raise Exception(f"Error executing command: {_clean_secrets(command)} \n {_clean_secrets(output)}") except Exception as ex: - logger.error(f"Error executing command: {command} \n {ex}") + logger.error(f"Error executing command: {_clean_secrets(command)} \n {ex}") raise ex return output +def _clean_secrets(data_to_clean): + """Clean secrets from the output.""" + if ( + hasattr(context.scenario, "api_key") + and context.scenario.api_key + and hasattr(context.scenario, "app_key") + and context.scenario.app_key + ): + data_to_clean = data_to_clean.replace(context.scenario.api_key, "DD_API_KEY").replace( + context.scenario.app_key, "DD_APP_KEY" + ) + return data_to_clean + + @retry(delay=1, tries=5) def execute_command_sync(command, k8s_kind_cluster, timeout=None, logfile=None): - """ Execute a command in the k8s cluster, but we use a lock to change the context of kubectl.""" + """Execute a command in the k8s cluster, but we use a lock to change the context of kubectl.""" with KubectlLock(): execute_command(f"kubectl config use-context {k8s_kind_cluster.context_name}", logfile=logfile) @@ -60,7 +81,6 @@ def execute_command_sync(command, k8s_kind_cluster, timeout=None, logfile=None): @retry(delay=1, tries=5) def helm_add_repo(name, url, k8s_kind_cluster, update=False): - with KubectlLock(): execute_command(f"kubectl config use-context {k8s_kind_cluster.context_name}") execute_command(f"helm repo add {name} {url}") @@ -69,18 +89,14 @@ def helm_add_repo(name, url, k8s_kind_cluster, update=False): @retry(delay=1, tries=5) -def helm_install_chart( - k8s_kind_cluster, name, chart, set_dict={}, value_file=None, prefix_library_init_image=None, upgrade=False -): +def helm_install_chart(k8s_kind_cluster, name, chart, set_dict={}, value_file=None, upgrade=False): # Copy and replace cluster name in the value file custom_value_file = None if value_file: - with open(value_file, "r") as file: + with open(value_file) as file: value_data = file.read() value_data = value_data.replace("$$CLUSTER_NAME$$", str(k8s_kind_cluster.cluster_name)) - if prefix_library_init_image: - value_data = value_data.replace("$$PREFIX_INIT_IMAGE$$", prefix_library_init_image) custom_value_file = f"{context.scenario.host_log_folder}/{k8s_kind_cluster.cluster_name}_help_values.yaml" @@ -108,7 +124,14 @@ def helm_install_chart( def path_clusterrole(k8s_kind_cluster): - """ This is a hack until the patching permission is added in the official helm chart.""" + """Hack until the patching permission is added in the official helm chart.""" with KubectlLock(): execute_command(f"kubectl config use-context {k8s_kind_cluster.context_name}") execute_command("sh utils/k8s_lib_injection/resources/operator/scripts/path_clusterrole.sh") + + +def kubectl_apply(k8s_kind_cluster, file): + """Apply template in a cluster.""" + with KubectlLock(): + execute_command(f"kubectl config use-context {k8s_kind_cluster.context_name}") + execute_command("kubectl apply -f " + file) diff --git a/utils/k8s_lib_injection/k8s_datadog_cluster_agent.py b/utils/k8s_lib_injection/k8s_datadog_cluster_agent.py deleted file mode 100644 index 81f6e9b64d9..00000000000 --- a/utils/k8s_lib_injection/k8s_datadog_cluster_agent.py +++ /dev/null @@ -1,341 +0,0 @@ -import time -import os -import json - -from kubernetes import client, watch - -from utils.k8s_lib_injection.k8s_command_utils import ( - helm_add_repo, - helm_install_chart, - execute_command_sync, - path_clusterrole, -) -from utils.k8s_lib_injection.k8s_logger import k8s_logger - - -class K8sDatadogClusterTestAgent: - def __init__(self, prefix_library_init_image, output_folder, test_name): - self.k8s_kind_cluster = None - self.prefix_library_init_image = prefix_library_init_image - self.output_folder = output_folder - self.test_name = test_name - self.logger = None - self.k8s_wrapper = None - - def configure(self, k8s_kind_cluster, k8s_wrapper): - self.k8s_kind_cluster = k8s_kind_cluster - self.k8s_wrapper = k8s_wrapper - self.logger = k8s_logger(self.output_folder, self.test_name, "k8s_logger") - self.logger.info(f"K8sDatadogClusterTestAgent configured with cluster: {self.k8s_kind_cluster.cluster_name}") - - def desploy_test_agent(self): - """ Installs the test agent pod.""" - - self.logger.info( - f"[Test agent] Deploying Datadog test agent on the cluster: {self.k8s_kind_cluster.cluster_name}" - ) - - container = client.V1Container( - name="trace-agent", - image="ghcr.io/datadog/dd-apm-test-agent/ddapm-test-agent:latest", - image_pull_policy="Always", - ports=[client.V1ContainerPort(container_port=8126, host_port=8126, name="traceport", protocol="TCP")], - command=["ddapm-test-agent"], - env=[ - client.V1EnvVar(name="SNAPSHOT_CI", value="0"), - client.V1EnvVar(name="PORT", value="8126"), - client.V1EnvVar(name="DD_APM_RECEIVER_SOCKET", value="/var/run/datadog/apm.socket"), - client.V1EnvVar(name="LOG_LEVEL", value="DEBUG"), - client.V1EnvVar( - name="ENABLED_CHECKS", value="trace_count_header,meta_tracer_version_header,trace_content_length" - ), - ], - volume_mounts=[client.V1VolumeMount(mount_path="/var/run/datadog", name="datadog")], - readiness_probe=client.V1Probe( - initial_delay_seconds=1, - period_seconds=2, - timeout_seconds=10, - success_threshold=1, - tcp_socket=client.V1TCPSocketAction(port=8126), - ), - liveness_probe=client.V1Probe( - initial_delay_seconds=15, - period_seconds=15, - timeout_seconds=10, - success_threshold=1, - failure_threshold=12, - tcp_socket=client.V1TCPSocketAction(port=8126), - ), - ) - # Template - template = client.V1PodTemplateSpec( - metadata=client.V1ObjectMeta(labels={"app": "datadog"}), - spec=client.V1PodSpec( - containers=[container], - dns_policy="ClusterFirst", - node_selector={"kubernetes.io/os": "linux"}, - restart_policy="Always", - scheduler_name="default-scheduler", - security_context=client.V1PodSecurityContext(run_as_user=0), - termination_grace_period_seconds=30, - volumes=[ - client.V1Volume( - name="datadog", - host_path=client.V1HostPathVolumeSource(path="/var/run/datadog", type="DirectoryOrCreate"), - ) - ], - ), - ) - # Spec - spec = client.V1DaemonSetSpec( - selector=client.V1LabelSelector(match_labels={"app": "datadog"}), template=template - ) - # DaemonSet - daemonset = client.V1DaemonSet( - api_version="apps/v1", kind="DaemonSet", metadata=client.V1ObjectMeta(name="datadog"), spec=spec - ) - - self.k8s_wrapper.create_namespaced_daemon_set(body=daemonset) - self.wait_for_test_agent() - self.logger.info("[Test agent] Daemonset created") - - def deploy_operator_manual(self, use_uds=False): - """ Installs the Datadog Cluster Agent via helm for manual library injection testing. - It returns when the Cluster Agent pod is ready.""" - - self.logger.info("[Deploy operator] Deploying Datadog Operator") - - operator_file = "utils/k8s_lib_injection/resources/operator/operator-helm-values.yaml" - if use_uds: - self.logger.info("[Deploy operator] Using UDS") - operator_file = "utils/k8s_lib_injection/resources/operator/operator-helm-values-uds.yaml" - - self.logger.info("[Deploy operator] Configuring helm repository") - helm_add_repo("datadog", "https://helm.datadoghq.com", self.k8s_kind_cluster, update=True) - - self.logger.info(f"[Deploy operator] helm install datadog with config file [{operator_file}]") - - helm_install_chart( - self.k8s_kind_cluster, - "datadog", - "datadog/datadog", - value_file=operator_file, - set_dict={"datadog.apiKey": os.getenv("DD_API_KEY"), "datadog.appKey": os.getenv("DD_APP_KEY")}, - ) - - self.logger.info("[Deploy operator] Waiting for the operator to be ready") - self._wait_for_operator_ready() - - def deploy_operator_auto(self): - """ Installs the Datadog Cluster Agent via helm for auto library injection testing. - It returns when the Cluster Agent pod is ready.""" - - self.logger.info("[Deploy operator] Using Patcher") - operator_file = "utils/k8s_lib_injection/resources/operator/operator-helm-values-auto.yaml" - - self.create_configmap_auto_inject() - self.logger.info("[Deploy operator] Configuring helm repository") - helm_add_repo("datadog", "https://helm.datadoghq.com", self.k8s_kind_cluster, update=True) - - self.logger.info(f"[Deploy operator] helm install datadog with config file [{operator_file}]") - - helm_install_chart( - self.k8s_kind_cluster, - "datadog", - "datadog/datadog", - value_file=operator_file, - set_dict={"datadog.apiKey": os.getenv("DD_API_KEY"), "datadog.appKey": os.getenv("DD_APP_KEY")}, - prefix_library_init_image=self.prefix_library_init_image, - ) - self._wait_for_operator_ready() - - # TODO: This is a hack until the patching permission is added in the official helm chart. - self.logger.info("[Deploy operator] adding patch permissions to the datadog-cluster-agent clusterrole") - path_clusterrole(self.k8s_kind_cluster) - - self._wait_for_operator_ready() - - def apply_config_auto_inject(self, config_data, rev=0): - """ Applies an configuration change for auto injection. - It returns when the targeted deployment finishes the rollout.""" - - self.logger.info(f"[Auto Config] Applying config for auto-inject: {config_data}") - metadata = client.V1ObjectMeta(name="auto-instru", namespace="default",) - configmap = client.V1ConfigMap(kind="ConfigMap", data={"auto-instru.json": config_data,}, metadata=metadata) - r = self.k8s_wrapper.replace_namespaced_config_map(name="auto-instru", body=configmap) - self.logger.info(f"[Auto Config] Configmap replaced!") - k8s_logger(self.output_folder, self.test_name, "applied_configmaps").info(r) - self.wait_configmap_auto_inject(timeout=150, rev=rev) - - def create_configmap_auto_inject(self): - """ Minimal configuration needed when we install operator auto """ - - self.logger.info("[Auto Config] Creating configmap for auto-inject") - metadata = client.V1ObjectMeta(name="auto-instru", namespace="default",) - configmap = client.V1ConfigMap( - kind="ConfigMap", - data={ - "auto-instru.json": """| - []""", - }, - metadata=metadata, - ) - self.k8s_wrapper.create_namespaced_config_map(body=configmap) - time.sleep(5) - - def wait_configmap_auto_inject(self, timeout=90, rev=0): - """ wait for the configmap to be read by the datadog-cluster-agent.""" - - patch_id = "11777398274940883092" - self.logger.info("[Auto Config] Waiting for the configmap to be read by the datadog-cluster-agent.") - # First we need to wait for the configmap to be created - w = watch.Watch() - for event in w.stream( - func=self.k8s_wrapper.list_namespaced_config_map, namespace="default", timeout_seconds=timeout - ): - k8s_logger(self.output_folder, self.test_name, "events_configmaps").info(event) - if ( - event["type"] == "ADDED" - and hasattr(event["object"], "metadata") - and event["object"].metadata.name == "auto-instru" - ): - self.logger.info("[Auto Config] Configmap applied!") - w.stop() - break - - # Second wait for datadog-cluster-agent read the configmap - expected_log = f'Applying Remote Config ID "{patch_id}" with revision "{rev}" and action' - pods = self.k8s_wrapper.list_namespaced_pod("default", label_selector="app=datadog-cluster-agent") - assert len(pods.items) > 0, "No pods found for app datadog-cluster-agent" - pod_cluster_agent_name = pods.items[0].metadata.name - timeout = time.time() + timeout - while True: - api_response = self.k8s_wrapper.read_namespaced_pod_log(name=pod_cluster_agent_name) - if api_response is not None: - for log_line in api_response.splitlines(): - if log_line.find(expected_log) != -1: - self.logger.info(f"Configmap read by datadog-cluster-agent: {log_line}") - return - if time.time() > timeout: - self.logger.error(f"Timeout waiting for the datadog-cluster-agent to read the configmap") - raise TimeoutError("Timeout waiting for the datadog-cluster-agent to read the configmap") - time.sleep(5) - - def wait_for_test_agent(self): - """ Waits for the test agent to be ready.""" - daemonset_created = False - daemonset_status = None - # Wait for the daemonset to be created - for i in range(20): - daemonset_status = self.k8s_wrapper.read_namespaced_daemon_set_status(name="datadog") - if daemonset_status is not None and daemonset_status.status.number_ready > 0: - self.logger.info(f"[Test agent] daemonset status datadog running!") - daemonset_created = True - break - time.sleep(5) - - if not daemonset_created: - self.logger.info("[Test agent] Daemonset not created. Last status: %s" % daemonset_status) - raise Exception("Daemonset not created") - - w = watch.Watch() - for event in w.stream( - func=self.k8s_wrapper.list_namespaced_pod, - namespace="default", - label_selector="app=datadog", - timeout_seconds=60, - ): - if "status" in event["object"] and event["object"]["status"]["phase"] == "Running": - w.stop() - self.logger.info("Datadog test agent started!") - break - - def _wait_for_operator_ready(self): - operator_ready = False - operator_status = None - datadog_cluster_name = None - - for i in range(20): - try: - if datadog_cluster_name is None: - pods = self.k8s_wrapper.list_namespaced_pod("default", label_selector="app=datadog-cluster-agent") - datadog_cluster_name = pods.items[0].metadata.name if pods and len(pods.items) > 0 else None - operator_status = ( - self.k8s_wrapper.read_namespaced_pod_status(name=datadog_cluster_name) - if datadog_cluster_name - else None - ) - if ( - operator_status - and operator_status.status.phase == "Running" - and operator_status.status.container_statuses[0].ready == True - ): - self.logger.info(f"[Deploy operator] Operator datadog running!") - operator_ready = True - break - except Exception as e: - self.logger.info(f"Error waiting for operator: {e}") - time.sleep(5) - - if not operator_ready: - self.logger.error("Operator not created. Last status: %s" % operator_status) - if datadog_cluster_name: - operator_logs = self.k8s_wrapper.read_namespaced_pod_log(name=datadog_cluster_name) - self.logger.error(f"Operator logs: {operator_logs}") - raise Exception("Operator not created") - # At this point the operator should be ready, we are going to wait a little bit more - # to make sure the operator is ready (some times the operator is ready but the cluster agent is not ready yet) - time.sleep(5) - - def export_debug_info(self): - """ Exports debug information for the test agent and the operator. - We shouldn't raise any exception here, we just log the errors.""" - - # Get all pods - ret = self.k8s_wrapper.list_namespaced_pod("default", watch=False) - if ret is not None: - for i in ret.items: - k8s_logger(self.output_folder, self.test_name, "get.pods").info( - "%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name) - ) - execute_command_sync( - f"kubectl get event --field-selector involvedObject.name={i.metadata.name}", - self.k8s_kind_cluster, - logfile=f"{self.output_folder}/{i.metadata.name}_events.log", - ) - - # Get all deployments - deployments = self.k8s_wrapper.list_deployment_for_all_namespaces() - if deployments is not None: - for deployment in deployments.items: - k8s_logger(self.output_folder, self.test_name, "get.deployments").info(deployment) - - # Daemonset describe - api_response = self.k8s_wrapper.read_namespaced_daemon_set(name="datadog") - k8s_logger(self.output_folder, self.test_name, "daemon.set.describe").info(api_response) - - # Cluster logs, admission controller - try: - pods = self.k8s_wrapper.list_namespaced_pod("default", label_selector="app=datadog-cluster-agent") - assert len(pods.items) > 0, "No pods found for app datadog-cluster-agent" - api_response = self.k8s_wrapper.read_namespaced_pod_log( - name=pods.items[0].metadata.name, namespace="default" - ) - k8s_logger(self.output_folder, self.test_name, "datadog-cluster-agent").info(api_response) - - # Export: Telemetry datadog-cluster-agent - execute_command_sync( - f"kubectl exec -it {pods.items[0].metadata.name} -- agent telemetry ", - self.k8s_kind_cluster, - logfile=f"{self.output_folder}/{pods.items[0].metadata.name}_telemetry.log", - ) - - # Export: Status datadog-cluster-agent - # Sometimes this command fails. Ignore this error - execute_command_sync( - f"kubectl exec -it {pods.items[0].metadata.name} -- agent status || true ", - self.k8s_kind_cluster, - logfile=f"{self.output_folder}/{pods.items[0].metadata.name}_status.log", - ) - except Exception as e: - self.logger.error(f"Error exporting datadog-cluster-agent logs: {e}") diff --git a/utils/k8s_lib_injection/k8s_datadog_kubernetes.py b/utils/k8s_lib_injection/k8s_datadog_kubernetes.py new file mode 100644 index 00000000000..f4544cb836e --- /dev/null +++ b/utils/k8s_lib_injection/k8s_datadog_kubernetes.py @@ -0,0 +1,262 @@ +import time + +from kubernetes import client, watch + +from utils.k8s_lib_injection.k8s_command_utils import ( + helm_add_repo, + helm_install_chart, + execute_command_sync, +) +from utils.k8s_lib_injection.k8s_logger import k8s_logger + + +class K8sDatadog: + def __init__(self, output_folder, test_name, api_key=None, app_key=None): + self.k8s_kind_cluster = None + self.output_folder = output_folder + self.test_name = test_name + self.logger = None + self.k8s_wrapper = None + self._api_key = api_key + self._app_key = app_key + + def configure( + self, k8s_kind_cluster, k8s_wrapper, dd_cluster_feature=None, dd_cluster_uds=None, k8s_cluster_version=None + ): + self.k8s_kind_cluster = k8s_kind_cluster + self.k8s_wrapper = k8s_wrapper + self.logger = k8s_logger(self.output_folder, self.test_name, "k8s_logger") + self.dd_cluster_feature = dd_cluster_feature + self.dd_cluster_uds = dd_cluster_uds + self.k8s_cluster_version = k8s_cluster_version + self.logger.info(f"K8sDatadog configured with cluster: {self.k8s_kind_cluster.cluster_name}") + + def deploy_test_agent(self): + """Installs the test agent pod.""" + + self.logger.info( + f"[Test agent] Deploying Datadog test agent on the cluster: {self.k8s_kind_cluster.cluster_name}" + ) + + container = client.V1Container( + name="trace-agent", + image="ghcr.io/datadog/dd-apm-test-agent/ddapm-test-agent:latest", + image_pull_policy="Always", + ports=[client.V1ContainerPort(container_port=8126, host_port=8126, name="traceport", protocol="TCP")], + command=["ddapm-test-agent"], + env=[ + client.V1EnvVar(name="SNAPSHOT_CI", value="0"), + client.V1EnvVar(name="PORT", value="8126"), + client.V1EnvVar(name="DD_APM_RECEIVER_SOCKET", value="/var/run/datadog/apm.socket"), + client.V1EnvVar(name="LOG_LEVEL", value="DEBUG"), + client.V1EnvVar( + name="ENABLED_CHECKS", value="trace_count_header,meta_tracer_version_header,trace_content_length" + ), + ], + volume_mounts=[client.V1VolumeMount(mount_path="/var/run/datadog", name="datadog")], + readiness_probe=client.V1Probe( + initial_delay_seconds=1, + period_seconds=2, + timeout_seconds=10, + success_threshold=1, + tcp_socket=client.V1TCPSocketAction(port=8126), + ), + liveness_probe=client.V1Probe( + initial_delay_seconds=15, + period_seconds=15, + timeout_seconds=10, + success_threshold=1, + failure_threshold=12, + tcp_socket=client.V1TCPSocketAction(port=8126), + ), + ) + # Template + template = client.V1PodTemplateSpec( + metadata=client.V1ObjectMeta(labels={"app": "datadog"}), + spec=client.V1PodSpec( + containers=[container], + dns_policy="ClusterFirst", + node_selector={"kubernetes.io/os": "linux"}, + restart_policy="Always", + scheduler_name="default-scheduler", + security_context=client.V1PodSecurityContext(run_as_user=0), + termination_grace_period_seconds=30, + volumes=[ + client.V1Volume( + name="datadog", + host_path=client.V1HostPathVolumeSource(path="/var/run/datadog", type="DirectoryOrCreate"), + ) + ], + ), + ) + # Spec + spec = client.V1DaemonSetSpec( + selector=client.V1LabelSelector(match_labels={"app": "datadog"}), template=template + ) + # DaemonSet + daemonset = client.V1DaemonSet( + api_version="apps/v1", kind="DaemonSet", metadata=client.V1ObjectMeta(name="datadog"), spec=spec + ) + + self.k8s_wrapper.create_namespaced_daemon_set(body=daemonset) + self.wait_for_test_agent() + self.logger.info("[Test agent] Daemonset created") + + def deploy_datadog_cluster_agent(self, use_uds=False, features={}, cluster_agent_tag=None): + """Installs the Datadog Cluster Agent via helm for manual library injection testing. + It returns when the Cluster Agent pod is ready. + """ + + self.logger.info("[Deploy datadog cluster] Deploying Datadog Cluster Agent with Admission Controler") + + if self.dd_cluster_uds is not None: + use_uds = self.dd_cluster_uds + if self.dd_cluster_feature is not None: + features = self.dd_cluster_feature + if self.k8s_cluster_version is not None: + cluster_agent_tag = self.k8s_cluster_version + + operator_file = "utils/k8s_lib_injection/resources/operator/operator-helm-values.yaml" + if use_uds: + self.logger.info("[Deploy datadog cluster] Using UDS") + operator_file = "utils/k8s_lib_injection/resources/operator/operator-helm-values-uds.yaml" + + self.logger.info("[Deploy datadog cluster] Configuring helm repository") + helm_add_repo("datadog", "https://helm.datadoghq.com", self.k8s_kind_cluster, update=True) + + self.logger.info(f"[Deploy datadog cluster]helm install datadog with config file [{operator_file}]") + datadog_keys = {"datadog.apiKey": self._api_key, "datadog.appKey": self._app_key} + if features: + features = features | datadog_keys + else: + features = datadog_keys + # Add the cluster agent tag version + features["clusterAgent.image.tag"] = cluster_agent_tag + helm_install_chart( + self.k8s_kind_cluster, "datadog", "datadog/datadog", value_file=operator_file, set_dict=features + ) + + self.logger.info("[Deploy datadog cluster] Waiting for the cluster to be ready") + self._wait_for_operator_ready() + + def wait_for_test_agent(self): + """Waits for the test agent to be ready.""" + daemonset_created = False + daemonset_status = None + # Wait for the daemonset to be created + for i in range(20): + daemonset_status = self.k8s_wrapper.read_namespaced_daemon_set_status(name="datadog") + if daemonset_status is not None and daemonset_status.status.number_ready > 0: + self.logger.info(f"[Test agent] daemonset status datadog running!") + daemonset_created = True + break + elif daemonset_status is None: + self.logger.info(f"[Test agent] daemonset status datadog not found") + time.sleep(5) + + if not daemonset_created: + self.logger.info("[Test agent] Daemonset not created. Last status: %s" % daemonset_status) + raise Exception("Daemonset not created") + + w = watch.Watch() + for event in w.stream( + func=self.k8s_wrapper.list_namespaced_pod, + namespace="default", + label_selector="app=datadog", + timeout_seconds=60, + ): + if "status" in event["object"] and event["object"]["status"]["phase"] == "Running": + w.stop() + self.logger.info("Datadog test agent started!") + break + + def _wait_for_operator_ready(self): + operator_ready = False + operator_status = None + datadog_cluster_name = None + + for i in range(20): + try: + if datadog_cluster_name is None: + pods = self.k8s_wrapper.list_namespaced_pod("default", label_selector="app=datadog-cluster-agent") + datadog_cluster_name = pods.items[0].metadata.name if pods and len(pods.items) > 0 else None + operator_status = ( + self.k8s_wrapper.read_namespaced_pod_status(name=datadog_cluster_name) + if datadog_cluster_name + else None + ) + if ( + operator_status + and operator_status.status.phase == "Running" + and operator_status.status.container_statuses[0].ready == True + ): + self.logger.info(f"[Deploy operator] Operator datadog running!") + operator_ready = True + break + except Exception as e: + self.logger.info(f"Error waiting for operator: {e}") + time.sleep(5) + + if not operator_ready: + self.logger.error("Operator not created. Last status: %s" % operator_status) + if datadog_cluster_name: + operator_logs = self.k8s_wrapper.read_namespaced_pod_log(name=datadog_cluster_name) + self.logger.error(f"Operator logs: {operator_logs}") + raise Exception("Operator not created") + # At this point the operator should be ready, we are going to wait a little bit more + # to make sure the operator is ready (some times the operator is ready but the cluster agent is not ready yet) + time.sleep(5) + + def export_debug_info(self): + """Exports debug information for the test agent and the operator. + We shouldn't raise any exception here, we just log the errors. + """ + + # Get all pods + ret = self.k8s_wrapper.list_namespaced_pod("default", watch=False) + if ret is not None: + for i in ret.items: + k8s_logger(self.output_folder, self.test_name, "get.pods").info( + "%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name) + ) + execute_command_sync( + f"kubectl get event --field-selector involvedObject.name={i.metadata.name}", + self.k8s_kind_cluster, + logfile=f"{self.output_folder}/{i.metadata.name}_events.log", + ) + + # Get all deployments + deployments = self.k8s_wrapper.list_deployment_for_all_namespaces() + if deployments is not None: + for deployment in deployments.items: + k8s_logger(self.output_folder, self.test_name, "get.deployments").info(deployment) + + # Daemonset describe + api_response = self.k8s_wrapper.read_namespaced_daemon_set(name="datadog") + k8s_logger(self.output_folder, self.test_name, "daemon.set.describe").info(api_response) + + # Cluster logs, admission controller + try: + pods = self.k8s_wrapper.list_namespaced_pod("default", label_selector="app=datadog-cluster-agent") + assert len(pods.items) > 0, "No pods found for app datadog-cluster-agent" + api_response = self.k8s_wrapper.read_namespaced_pod_log( + name=pods.items[0].metadata.name, namespace="default" + ) + k8s_logger(self.output_folder, self.test_name, "datadog-cluster-agent").info(api_response) + + # Export: Telemetry datadog-cluster-agent + execute_command_sync( + f"kubectl exec -it {pods.items[0].metadata.name} -- agent telemetry ", + self.k8s_kind_cluster, + logfile=f"{self.output_folder}/{pods.items[0].metadata.name}_telemetry.log", + ) + + # Export: Status datadog-cluster-agent + # Sometimes this command fails. Ignore this error + execute_command_sync( + f"kubectl exec -it {pods.items[0].metadata.name} -- agent status || true ", + self.k8s_kind_cluster, + logfile=f"{self.output_folder}/{pods.items[0].metadata.name}_status.log", + ) + except Exception as e: + self.logger.error(f"Error exporting datadog-cluster-agent logs: {e}") diff --git a/utils/k8s_lib_injection/k8s_kind_cluster.py b/utils/k8s_lib_injection/k8s_kind_cluster.py index 3e18ec969f3..caf6fcf4a51 100644 --- a/utils/k8s_lib_injection/k8s_kind_cluster.py +++ b/utils/k8s_lib_injection/k8s_kind_cluster.py @@ -1,30 +1,26 @@ -import time import os -import socket -import random -import tempfile from uuid import uuid4 -from utils.k8s_lib_injection.k8s_command_utils import execute_command -from utils.tools import logger +from utils.k8s_lib_injection.k8s_command_utils import execute_command, execute_command_sync +from utils.tools import logger, get_free_port from utils import context def ensure_cluster(): try: - return _ensure_cluster() + k8s_kind_cluster = K8sKindCluster() + return _ensure_cluster(k8s_kind_cluster) except Exception as e: # It's difficult, but sometimes the cluster is not created correctly, releated to the ports conflicts logger.error(f"Error ensuring cluster: {e}. trying again.") - return _ensure_cluster() + return _ensure_cluster(k8s_kind_cluster) -def _ensure_cluster(): - k8s_kind_cluster = K8sKindCluster() - k8s_kind_cluster.confiure_ports() +def _ensure_cluster(k8s_kind_cluster): + k8s_kind_cluster.configure_networking(docker_in_docker="GITLAB_CI" in os.environ) kind_data = "" - with open("utils/k8s_lib_injection/resources/kind-config-template.yaml", "r") as file: + with open("utils/k8s_lib_injection/resources/kind-config-template.yaml") as file: kind_data = file.read() kind_data = kind_data.replace("$$AGENT_PORT$$", str(k8s_kind_cluster.agent_port)) @@ -35,11 +31,18 @@ def _ensure_cluster(): with open(cluster_config, "w") as fp: fp.write(kind_data) fp.seek(0) - execute_command( - f"kind create cluster --image=kindest/node:v1.25.3@sha256:f52781bc0d7a19fb6c405c2af83abfeb311f130707a0e219175677e366cc45d1 --name {k8s_kind_cluster.cluster_name} --config {cluster_config} --wait 1m" - ) - # time.sleep(20) + kind_command = f"kind create cluster --image=kindest/node:v1.25.3@sha256:f52781bc0d7a19fb6c405c2af83abfeb311f130707a0e219175677e366cc45d1 --name {k8s_kind_cluster.cluster_name} --config {cluster_config} --wait 1m" + + if "GITLAB_CI" in os.environ: + # Kind needs to run in bridge network to communicate with the internet: https://github.com/DataDog/buildenv/blob/master/cookbooks/dd_firewall/templates/rules.erb#L96 + new_env = os.environ.copy() + new_env["KIND_EXPERIMENTAL_DOCKER_NETWORK"] = "bridge" + execute_command(kind_command, subprocess_env=new_env) + + setup_kind_in_gitlab(k8s_kind_cluster) + else: + execute_command(kind_command) return k8s_kind_cluster @@ -49,28 +52,86 @@ def destroy_cluster(k8s_kind_cluster): execute_command(f"docker rm -f {k8s_kind_cluster.cluster_name}-control-plane") -def get_free_port(): - last_allowed_port = 65535 - port = random.randint(1100, 65100) - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - while port <= last_allowed_port: - try: - sock.bind(("", port)) - sock.close() - return port - except OSError: - port += 1 - raise IOError("no free ports") +def setup_kind_in_gitlab(k8s_kind_cluster): + # The build runs in a docker container: + # - Docker commands are forwarded to the host. + # - The kind container is a sibling to the build container + # Three things need to happen + # 1) The kind container needs to be in the bridge network to communicate with the internet: done in _ensure_cluster() + # 2) Kube config needs to be altered to use the correct IP of the control plane server + # 3) The internal ports needs to be used rather than external ports: handled in get_agent_port() and get_weblog_port() + correct_control_plane_ip = execute_command( + f"docker container inspect {k8s_kind_cluster.cluster_name}-control-plane --format '{{{{.NetworkSettings.Networks.bridge.IPAddress}}}}'" + ).strip() + if not correct_control_plane_ip: + raise Exception("Unable to find correct control plane IP") + logger.debug(f"[setup_kind_in_gitlab] correct_control_plane_ip: {correct_control_plane_ip}") + + control_plane_address_in_config = execute_command( + f'docker container inspect {k8s_kind_cluster.cluster_name}-control-plane --format \'{{{{index .NetworkSettings.Ports "6443/tcp" 0 "HostIp"}}}}:{{{{index .NetworkSettings.Ports "6443/tcp" 0 "HostPort"}}}}\'' + ).strip() + if not control_plane_address_in_config: + raise Exception("Unable to find control plane address from config") + logger.debug(f"[setup_kind_in_gitlab] control_plane_address_in_config: {control_plane_address_in_config}") + + # Replace server config with dns name + internal port + execute_command_sync( + f"sed -i -e 's/{control_plane_address_in_config}/{correct_control_plane_ip}:6443/g' {os.environ['HOME']}/.kube/config", + k8s_kind_cluster, + ) + + k8s_kind_cluster.cluster_host_name = correct_control_plane_ip class K8sKindCluster: def __init__(self): self.cluster_name = f"lib-injection-testing-{str(uuid4())[:8]}" self.context_name = f"kind-{self.cluster_name}" - self.agent_port = 18126 - self.weblog_port = 18080 - - def confiure_ports(self): - # Get random free ports + self.cluster_host_name = "localhost" + self.agent_port = None + self.weblog_port = None + self.internal_agent_port = None + self.internal_weblog_port = None + self.docker_in_docker = False + + def configure_networking(self, docker_in_docker=False): + self.docker_in_docker = docker_in_docker self.agent_port = get_free_port() self.weblog_port = get_free_port() + self.internal_agent_port = 8126 + self.internal_weblog_port = 18080 + + def get_agent_port(self): + if self.docker_in_docker: + return self.internal_agent_port + return self.agent_port + + def get_weblog_port(self): + if self.docker_in_docker: + return self.internal_weblog_port + return self.weblog_port + + +default_kind_cluster = K8sKindCluster() + + +def create_cluster(): + try: + return _ensure_cluster(default_kind_cluster) + except Exception as e: + # It's difficult, but sometimes the cluster is not created correctly, releated to the ports conflicts + logger.error(f"Error ensuring cluster: {e}. trying again.") + return _ensure_cluster(default_kind_cluster) + + +def delete_cluster(): + destroy_cluster(default_kind_cluster) + + +def create_spak_service_account(): + """Create service account for launching spark application in k8s""" + execute_command_sync(f"kubectl create serviceaccount spark", default_kind_cluster) + execute_command_sync( + f"kubectl create clusterrolebinding spark-role --clusterrole=edit --serviceaccount=default:spark --namespace=default", + default_kind_cluster, + ) diff --git a/utils/k8s_lib_injection/k8s_sync_kubectl.py b/utils/k8s_lib_injection/k8s_sync_kubectl.py index 89795c6d0fc..2e530df30b1 100644 --- a/utils/k8s_lib_injection/k8s_sync_kubectl.py +++ b/utils/k8s_lib_injection/k8s_sync_kubectl.py @@ -9,28 +9,30 @@ class KubectlLockException(Exception): class KubectlLock(object): - """ A file locking mechanism that has context-manager support so - you can use it in a with statement. This should be relatively cross - compatible as it doesn't rely on msvcrt or fcntl for the locking. + """A file locking mechanism that has context-manager support so + you can use it in a with statement. This should be relatively cross + compatible as it doesn't rely on msvcrt or fcntl for the locking. """ - def __init__(self, file_name=f"{context.scenario.host_log_folder}/kubectl.sync", timeout=60, delay=0.05): - """ Prepare the file locker. Specify the file to lock and optionally - the maximum timeout and the delay between each attempt to lock. + def __init__(self, timeout=60, delay=0.05): + """Prepare the file locker. Specify the file to lock and optionally + the maximum timeout and the delay between each attempt to lock. """ if timeout is not None and delay is None: raise ValueError("If timeout is not None, then delay must not be None.") self.is_locked = False + self.file_name = file_name = ( + f"{context.scenario.host_log_folder}/kubectl.sync" if context.scenario else "kubectl.sync" + ) self.lockfile = os.path.join(os.getcwd(), "%s.lock" % file_name) - self.file_name = file_name self.timeout = timeout self.delay = delay def acquire(self): - """ Acquire the lock, if possible. If the lock is in use, it check again - every `wait` seconds. It does this until it either gets the lock or - exceeds `timeout` number of seconds, in which case it throws - an exception. + """Acquire the lock, if possible. If the lock is in use, it check again + every `wait` seconds. It does this until it either gets the lock or + exceeds `timeout` number of seconds, in which case it throws + an exception. """ start_time = time.time() while True: @@ -50,9 +52,9 @@ def acquire(self): # self.is_locked = True def release(self): - """ Get rid of the lock by deleting the lockfile. - When working in a `with` statement, this gets automatically - called at the end. + """Get rid of the lock by deleting the lockfile. + When working in a `with` statement, this gets automatically + called at the end. """ if self.is_locked: os.close(self.fd) @@ -60,22 +62,22 @@ def release(self): self.is_locked = False def __enter__(self): - """ Activated when used in the with statement. - Should automatically acquire a lock to be used in the with block. + """Activated when used in the with statement. + Should automatically acquire a lock to be used in the with block. """ if not self.is_locked: self.acquire() return self def __exit__(self, type, value, traceback): - """ Activated at the end of the with statement. - It automatically releases the lock if it isn't locked. + """Activated at the end of the with statement. + It automatically releases the lock if it isn't locked. """ if self.is_locked: self.release() def __del__(self): - """ Make sure that the FileLock instance doesn't leave a lockfile - lying around. + """Make sure that the FileLock instance doesn't leave a lockfile + lying around. """ self.release() diff --git a/utils/k8s_lib_injection/k8s_weblog.py b/utils/k8s_lib_injection/k8s_weblog.py index 6dbaf0eb3a6..cbd9992e0ab 100644 --- a/utils/k8s_lib_injection/k8s_weblog.py +++ b/utils/k8s_lib_injection/k8s_weblog.py @@ -1,5 +1,4 @@ -import time, datetime -from kubernetes import client, config, watch +from kubernetes import client, watch from utils.k8s_lib_injection.k8s_logger import k8s_logger @@ -31,20 +30,27 @@ def __init__(self, app_image, library, library_init_image, output_folder, test_n self.logger = None self.k8s_wrapper = None - def configure(self, k8s_kind_cluster, k8s_wrapper): + def configure(self, k8s_kind_cluster, k8s_wrapper, weblog_env=None, dd_cluster_uds=None, service_account=None): self.k8s_kind_cluster = k8s_kind_cluster self.k8s_wrapper = k8s_wrapper + self.weblog_env = weblog_env + self.dd_cluster_uds = dd_cluster_uds + self.dd_service_account = service_account self.logger = k8s_logger(self.output_folder, self.test_name, "k8s_logger") - def _get_base_weblog_pod(self): - """ Installs a target app for manual library injection testing. - It returns when the app pod is ready.""" - + def _get_base_weblog_pod(self, env=None, service_account=None): + """Installs a target app for manual library injection testing. + It returns when the app pod is ready. + """ + if self.weblog_env is not None: + env = self.weblog_env + if self.dd_service_account is not None: + service_account = self.dd_service_account self.logger.info( "[Deploy weblog] Creating weblog pod configuration. weblog_variant_image: [%s], library: [%s], library_init_image: [%s]" % (self.app_image, self.library, self.library_init_image) ) - + library_lib = "js" if self.library == "nodejs" else self.library pod_metadata = client.V1ObjectMeta( name="my-app", namespace="default", @@ -55,39 +61,44 @@ def _get_base_weblog_pod(self): "tags.datadoghq.com/service": "my-app", "tags.datadoghq.com/version": "local", }, - annotations={f"admission.datadoghq.com/{self.library}-lib.custom-image": f"{self.library_init_image}"}, + annotations={f"admission.datadoghq.com/{library_lib}-lib.custom-image": f"{self.library_init_image}"}, ) containers = [] - container1 = client.V1Container( - name="my-app", - image=self.app_image, - env=[ - client.V1EnvVar(name="SERVER_PORT", value="18080"), - client.V1EnvVar( - name="DD_ENV", - value_from=client.V1EnvVarSource( - field_ref=client.V1ObjectFieldSelector(field_path="metadata.labels['tags.datadoghq.com/env']") - ), + # Set the default environment variables for all pods + default_pod_env = [ + client.V1EnvVar(name="SERVER_PORT", value="18080"), + client.V1EnvVar( + name="DD_ENV", + value_from=client.V1EnvVarSource( + field_ref=client.V1ObjectFieldSelector(field_path="metadata.labels['tags.datadoghq.com/env']") ), - client.V1EnvVar( - name="DD_SERVICE", - value_from=client.V1EnvVarSource( - field_ref=client.V1ObjectFieldSelector( - field_path="metadata.labels['tags.datadoghq.com/service']" - ) - ), + ), + client.V1EnvVar( + name="DD_SERVICE", + value_from=client.V1EnvVarSource( + field_ref=client.V1ObjectFieldSelector(field_path="metadata.labels['tags.datadoghq.com/service']") ), - client.V1EnvVar( - name="DD_VERSION", - value_from=client.V1EnvVarSource( - field_ref=client.V1ObjectFieldSelector( - field_path="metadata.labels['tags.datadoghq.com/version']" - ) - ), + ), + client.V1EnvVar( + name="DD_VERSION", + value_from=client.V1EnvVarSource( + field_ref=client.V1ObjectFieldSelector(field_path="metadata.labels['tags.datadoghq.com/version']") ), - client.V1EnvVar(name="DD_TRACE_DEBUG", value="1"), - ], + ), + client.V1EnvVar(name="DD_TRACE_DEBUG", value="1"), + client.V1EnvVar(name="DD_APM_INSTRUMENTATION_DEBUG", value="true"), + ] + # Add custom env vars if provided + if env: + for k, v in env.items(): + default_pod_env.append(client.V1EnvVar(name=k, value=v)) + + self.logger.info(f"Weblog pod env: {default_pod_env}") + container1 = client.V1Container( + name="my-app", + image=self.app_image, + env=default_pod_env, readiness_probe=client.V1Probe( timeout_seconds=5, success_threshold=3, @@ -101,21 +112,27 @@ def _get_base_weblog_pod(self): containers.append(container1) - pod_spec = client.V1PodSpec(containers=containers) + pod_spec = client.V1PodSpec(containers=containers, service_account=service_account) pod_body = client.V1Pod(api_version="v1", kind="Pod", metadata=pod_metadata, spec=pod_spec) self.logger.info("[Deploy weblog] Weblog pod configuration done.") return pod_body - def install_weblog_pod_with_admission_controller(self): + def install_weblog_pod_with_admission_controller(self, env=None, service_account=None): self.logger.info("[Deploy weblog] Installing weblog pod using admission controller") - pod_body = self._get_base_weblog_pod() + if self.weblog_env is not None: + env = self.weblog_env + if self.dd_service_account is not None: + service_account = self.dd_service_account + pod_body = self._get_base_weblog_pod(env=env, service_account=service_account) self.k8s_wrapper.create_namespaced_pod(body=pod_body) self.logger.info("[Deploy weblog] Weblog pod using admission controller created. Waiting for it to be ready!") self.wait_for_weblog_ready_by_label_app("my-app", timeout=200) - def install_weblog_pod_without_admission_controller(self, use_uds): - pod_body = self._get_base_weblog_pod() + def install_weblog_pod_without_admission_controller(self, use_uds=False, env=None): + if self.dd_cluster_uds is not None: + use_uds = self.dd_cluster_uds + pod_body = self._get_base_weblog_pod(env=env) pod_body.spec.init_containers = [] init_container1 = client.V1Container( command=["sh", "copy-lib.sh", "/datadog-lib"], @@ -129,7 +146,7 @@ def install_weblog_pod_without_admission_controller(self, use_uds): pod_body.spec.init_containers.append(init_container1) pod_body.spec.containers[0].env.append(client.V1EnvVar(name="DD_LOGS_INJECTION", value="true")) # Env vars for manual injection. Each library has its own env vars - for lang_env_vars in K8sWeblog.manual_injection_props[self.library]: + for lang_env_vars in K8sWeblog.manual_injection_props["js" if self.library == "nodejs" else self.library]: pod_body.spec.containers[0].env.append( client.V1EnvVar(name=lang_env_vars["name"], value=lang_env_vars["value"]) ) @@ -169,81 +186,6 @@ def install_weblog_pod_without_admission_controller(self, use_uds): self.k8s_wrapper.create_namespaced_pod(body=pod_body) self.wait_for_weblog_ready_by_label_app("my-app", timeout=200) - def deploy_app_auto(self): - """ Installs a target app for auto library injection testing. - It returns when the deployment is available and the rollout is finished.""" - deployment_name = f"test-{self.library}-deployment" - - deployment_metadata = client.V1ObjectMeta( - name=deployment_name, namespace="default", labels={"app": f"{self.library}-app"}, - ) - - # Configureate Pod template container - container = client.V1Container( - name=f"{self.library}-app", - image=self.app_image, - env=[client.V1EnvVar(name="SERVER_PORT", value="18080"),], - readiness_probe=client.V1Probe( - timeout_seconds=5, - success_threshold=3, - failure_threshold=10, - http_get=client.V1HTTPGetAction(path="/", port=18080), - initial_delay_seconds=20, - period_seconds=10, - ), - ports=[client.V1ContainerPort(container_port=18080, host_port=18080, name="http", protocol="TCP")], - ) - - # Create and configure a spec section - template = client.V1PodTemplateSpec( - metadata=client.V1ObjectMeta(labels={"app": f"{self.library}-app"}), - spec=client.V1PodSpec(containers=[container], restart_policy="Always"), - ) - - # Create the specification of deployment - spec = client.V1DeploymentSpec( - replicas=1, template=template, selector={"matchLabels": {"app": f"{self.library}-app"}} - ) - - # Instantiate the deployment object - deployment = client.V1Deployment( - api_version="apps/v1", kind="Deployment", metadata=deployment_metadata, spec=spec, - ) - # Create deployment. retry if it fails - self.k8s_wrapper.create_namespaced_deployment(body=deployment) - - self._wait_for_deployment_complete(deployment_name, timeout=180) - - def wait_for_weblog_after_apply_configmap(self, app_name, timeout=200): - """ Waits for the weblog to be ready after applying a configmap. We added a lot of debug traces - because we have seen some flakiness in the past.""" - pods = self.k8s_wrapper.list_namespaced_pod("default", label_selector=f"app={app_name}") - self.logger.info(f"[Weblog] Currently running pods [{app_name}]:[{len(pods.items)}]") - if len(pods.items) == 2: - for pod in pods.items: - self.logger.info(f"[Weblog] Pod name: {pod.metadata.name} - Pod status: {pod.status.phase}") - if pods.items[0].status.phase == "Pending" or pods.items[1].status.phase == "Pending": - pod_name_pending = ( - pods.items[0].metadata.name - if pods.items[0].status.phase == "Pending" - else pods.items[1].metadata.name - ) - pod_name_running = ( - pods.items[0].metadata.name - if pods.items[0].status.phase == "Running" - else pods.items[1].metadata.name - ) - - self.logger.info(f"[Weblog] Deleting previous pod {pod_name_running}") - self.k8s_wrapper.delete_namespaced_pod(pod_name_running, "default") - - # weird behavior, sometimes the pod is not deleted or a new one is created. Debug info is needed - time.sleep(5) - - self.logger.info(f"[Weblog] Waiting for pod {pod_name_pending} to be running") - self.wait_for_weblog_ready_by_pod_name(pod_name_pending, timeout=timeout) - self.logger.info(f"[Weblog] Pod {pod_name_pending} is ready") - def wait_for_weblog_ready_by_label_app(self, app_name, timeout=60): self.logger.info( f"[Deploy weblog] Waiting for weblog to be ready(by label) .App {app_name}. Timeout {timeout} seconds." @@ -273,53 +215,8 @@ def wait_for_weblog_ready_by_label_app(self, app_name, timeout=60): self.logger.error(f"[Deploy weblog] weblog logs: {pod_logs}") raise Exception("[Deploy weblog] Weblog not created") - def wait_for_weblog_ready_by_pod_name(self, pod_name, timeout=60): - self.logger.info( - f"[Deploy weblog] Waiting for weblog to be ready(by pod name) .App {pod_name}. Timeout {timeout} seconds." - ) - - start = datetime.datetime.now() - while True: - pod = self.k8s_wrapper.read_namespaced_pod(pod_name) - if pod is not None and pod.status.phase == "Running" and pod.status.container_statuses[0].ready: - self.logger.info("[Deploy weblog] Weblog pod started!") - return - time.sleep(1) - now = datetime.datetime.now() - if (now - start).seconds > timeout: - self.logger.error(f"[Deploy weblog] weblog did not start in {timeout} seconds") - raise Exception(f"Pod {pod_name} did not start in {timeout} seconds") - - def _wait_for_deployment_complete(self, deployment_name, timeout=60): - self.logger.info("[Deploy weblog] Waiting for weblog deployment complete!") - start = time.time() - while time.time() - start < timeout: - time.sleep(2) - try: - response = self.k8s_wrapper.read_namespaced_deployment_status(deployment_name, "default") - s = response.status if response is not None else None - if ( - s is not None - and s.updated_replicas == response.spec.replicas - and s.replicas == response.spec.replicas - and s.available_replicas == response.spec.replicas - and s.observed_generation >= response.metadata.generation - ): - self.logger.info("[Deploy weblog] Weblog deployment completed!") - return True - else: - if s is not None: - self.logger.info( - f"[updated_replicas:{s.updated_replicas},replicas:{s.replicas}" - f"available_replicas:{s.available_replicas},observed_generation:{s.observed_generation}] waiting..." - ) - except Exception as e: - self.logger.info(f"Error checking deployment status: {e}") - self.logger.error(f"[Deploy weblog: {deployment_name}] weblog deployment did not start in {timeout} seconds") - raise RuntimeError(f"Waiting timeout for deployment {deployment_name}") - def export_debug_info(self): - """ Extracts debug info from the k8s weblog app and logs it to the specified folder.""" + """Extracts debug info from the k8s weblog app and logs it to the specified folder.""" # check weblog describe pod try: diff --git a/utils/k8s_lib_injection/k8s_wrapper.py b/utils/k8s_lib_injection/k8s_wrapper.py index 059a304523f..5980aa41e67 100644 --- a/utils/k8s_lib_injection/k8s_wrapper.py +++ b/utils/k8s_lib_injection/k8s_wrapper.py @@ -1,14 +1,13 @@ -import time -from kubernetes import client, config, watch -from utils.tools import logger +from kubernetes import client, config from retry import retry class K8sWrapper: - """ Wrap methods from CoreV1Api and AppsV1Api to make it fail-safe. + """Wrap methods from CoreV1Api and AppsV1Api to make it fail-safe. In a simple execution, the methods used here are usually smooth. Problems arise when we run tests with a lot of parallelism. - We apply a retry policy """ + We apply a retry policy + """ def __init__(self, k8s_kind_cluster): self.k8s_kind_cluster = k8s_kind_cluster @@ -23,7 +22,7 @@ def apps_api(self): @retry(delay=1, tries=5) def create_namespaced_daemon_set(self, namespace="default", body=None): - self.apps_api().create_namespaced_daemon_set(namespace="default", body=body) + self.apps_api().create_namespaced_daemon_set(namespace=namespace, body=body) @retry(delay=1, tries=5) def read_namespaced_daemon_set_status(self, name=None, namespace="default"): @@ -68,23 +67,3 @@ def list_deployment_for_all_namespaces(self): @retry(delay=1, tries=5) def create_namespaced_pod(self, namespace="default", body=None): return self.core_v1_api().create_namespaced_pod(namespace=namespace, body=body) - - @retry(delay=1, tries=5) - def create_namespaced_deployment(self, body=None, namespace="default"): - return self.apps_api().create_namespaced_deployment(namespace=namespace, body=body) - - @retry(delay=1, tries=5) - def read_namespaced_deployment_status(self, deployment_name, namespace="default"): - return self.apps_api().read_namespaced_deployment_status(deployment_name, namespace=namespace) - - @retry(delay=1, tries=10) - def read_namespaced_deployment(self, deployment_name, namespace="default"): - return self.apps_api().read_namespaced_deployment(deployment_name, namespace=namespace) - - @retry(delay=1, tries=5) - def patch_namespaced_deployment(self, deployment_name, namespace, deploy_data): - return self.apps_api().patch_namespaced_deployment(deployment_name, namespace, deploy_data) - - @retry(delay=1, tries=5) - def delete_namespaced_pod(self, pod_name_running, namespace): - return self.core_v1_api().delete_namespaced_pod(pod_name_running, namespace=namespace) diff --git a/utils/k8s_lib_injection/resources/operator/operator-helm-values-auto.yaml b/utils/k8s_lib_injection/resources/operator/operator-helm-values-auto.yaml deleted file mode 100644 index 2a49ccb959c..00000000000 --- a/utils/k8s_lib_injection/resources/operator/operator-helm-values-auto.yaml +++ /dev/null @@ -1,47 +0,0 @@ -agents: - enabled: false -datadog: - clusterName: $$CLUSTER_NAME$$ - logLevel: DEBUG - apm: - enabled: true - portEnabled: true -clusterAgent: - livenessProbe: - initialDelaySeconds: 15 - periodSeconds: 15 - timeoutSeconds: 10 - successThreshold: 1 - failureThreshold: 12 - readinessProbe: - initialDelaySeconds: 15 - periodSeconds: 15 - timeoutSeconds: 10 - successThreshold: 1 - failureThreshold: 12 - image: - #tag: master - #repository: datadog/cluster-agent-dev - #tag: liliya-belaus-7-52-0-rc2-test - #repository: datadog/cluster-agent-dev - pullPolicy: Always - doNotCheckTag: true - env: - - name: DD_REMOTE_CONFIGURATION_ENABLED - value: "false" - - name: DD_ADMISSION_CONTROLLER_AUTO_INSTRUMENTATION_PATCHER_ENABLED - value: "true" - - name: DD_ADMISSION_CONTROLLER_AUTO_INSTRUMENTATION_PATCHER_FALLBACK_TO_FILE_PROVIDER - value: "true" - - name: DD_ADMISSION_CONTROLLER_AUTO_INSTRUMENTATION_CONTAINER_REGISTRY - value: "$$PREFIX_INIT_IMAGE$$" - volumes: - - name: auto-instru - configMap: - name: auto-instru - items: - - key: auto-instru.json - path: auto-instru.json - volumeMounts: - - name: auto-instru - mountPath: /etc/datadog-agent/patch diff --git a/utils/k8s_lib_injection/resources/operator/operator-helm-values.yaml b/utils/k8s_lib_injection/resources/operator/operator-helm-values.yaml index 9324f6b652f..3f6681e63db 100644 --- a/utils/k8s_lib_injection/resources/operator/operator-helm-values.yaml +++ b/utils/k8s_lib_injection/resources/operator/operator-helm-values.yaml @@ -29,7 +29,7 @@ clusterAgent: image: #comment name, tag and repository to test cluster-agent for local Mac M1 #name: "" - #tag: master + # tag: 7.57.0 #tag: liliya-belaus-7-52-0-rc2-test #repository: datadog/cluster-agent-dev pullPolicy: Always diff --git a/utils/onboarding/backend_interface.py b/utils/onboarding/backend_interface.py index a2617906b0a..a1c47f6f577 100644 --- a/utils/onboarding/backend_interface.py +++ b/utils/onboarding/backend_interface.py @@ -12,7 +12,7 @@ def _headers(): } -def _query_for_trace_id(trace_id): +def _query_for_trace_id(trace_id, validator=None): path = f"/api/v1/trace/{trace_id}" host = "https://dd.datadoghq.com" @@ -23,6 +23,12 @@ def _query_for_trace_id(trace_id): logger.debug(f" Backend response for trace_id [{trace_id}]: [{r.text}]") # Check if it's not a old trace trace_data = r.json() + if validator: + logger.info("Validating backend trace...") + if not validator(trace_id, trace_data): + logger.info("Backend trace is not valid") + return -1, None + logger.info("Backend trace is valid") root_id = trace_data["trace"]["root_id"] start_time = trace_data["trace"]["spans"][root_id]["start"] start_date = datetime.fromtimestamp(start_time) @@ -71,18 +77,18 @@ def _query_for_profile(runtime_id): return -1 -def wait_backend_trace_id(trace_id, timeout: float = 5.0, profile: bool = False): +def wait_backend_trace_id(trace_id, timeout: float = 5.0, profile: bool = False, validator=None): start_time = time.perf_counter() while True: - status, runtime_id = _query_for_trace_id(trace_id) + status, runtime_id = _query_for_trace_id(trace_id, validator=validator) if status != 200: - time.sleep(2) + time.sleep(3) else: logger.info(f"trace [{trace_id}] found in the backend!") if profile: while True: if _query_for_profile(runtime_id) != 200: - time.sleep(2) + time.sleep(3) else: logger.info(f"profile for trace [{trace_id}] (runtime [{runtime_id}]) found in the backend!") break diff --git a/utils/onboarding/debug_vm.py b/utils/onboarding/debug_vm.py index 5135f8feb7f..6b794d6225a 100644 --- a/utils/onboarding/debug_vm.py +++ b/utils/onboarding/debug_vm.py @@ -1,10 +1,29 @@ import os +from pathlib import Path import paramiko from utils.tools import logger +def extract_logs_to_file(logs_data, log_folder): + """Extract logs to different files. + The logs_data is a string results of executing the command: + find /var/log -type f -name "*.log"| xargs tail -n +1 + """ + + output_file = None + for line in logs_data.splitlines(): + if "==>" in line and "<==" in line: + filename = line.split("==>")[1].split("<==")[0] + logger.info(f"Copy log data from [{filename.strip()}]") + output_file = Path(log_folder + filename.strip()) + output_file.parent.mkdir(exist_ok=True, parents=True) + elif output_file is not None: + with open(output_file, "a", encoding="utf-8") as out: + out.write(f"{line}\n") + + def debug_info_ssh(vm_name, ip, user, pem_file, log_folder): - """ Using SSH connects to VM and extract VM status information """ + """Using SSH connects to VM and extract VM status information""" try: logger.info(f"Extracting debug information from machine {ip}") @@ -41,13 +60,13 @@ def _print_env_variables(sshClient, file_to_write): def _print_running_processes(sshClient, file_to_write): - """ Processes running on the machine """ + """Processes running on the machine""" _, stdout, _ = sshClient.exec_command("ps -fea") _write_to_debug_file(stdout, file_to_write) def _print_directories_permissions(sshClient, file_to_write): - """ List datadog directories permission """ + """List datadog directories permission""" permissions_command = """for dir in ` sudo find / -name "*datadog*" -type d -maxdepth 3`; do echo ".:: Folder: $dir ::." sudo ls -la $dir diff --git a/utils/onboarding/injection_log_parser.py b/utils/onboarding/injection_log_parser.py index 24a1f29b4eb..32781f4e59e 100644 --- a/utils/onboarding/injection_log_parser.py +++ b/utils/onboarding/injection_log_parser.py @@ -1,4 +1,5 @@ import json +import os from utils.tools import logger @@ -8,8 +9,9 @@ def exclude_telemetry_logs_filter(line): def command_injection_skipped(command_line, log_local_path): - """ From parsed log, search on the list of logged commands - if one command has been skipped from the instrumentation""" + """From parsed log, search on the list of logged commands + if one command has been skipped from the instrumentation + """ command, command_args = _parse_command(command_line) logger.debug(f"- Checking command: {command_args}") for command_desc in _get_commands_from_log_file(log_local_path, exclude_telemetry_logs_filter): @@ -25,17 +27,19 @@ def command_injection_skipped(command_line, log_local_path): elif last_line_json["msg"] == "not injecting; on user deny list": logger.debug(f" Command {command_args} was skipped by user defined deny process list") return True + elif last_line_json["msg"] in ["error injecting", "error when parsing", "skipping"] and ( + last_line_json["error"].startswith( + ( + "skipping due to ignore rules for language", + "error when parsing: skipping due to ignore rules for language", + ) + ) + ): + logger.info(f" Command {command_args} was skipped by ignore arguments") + return True + logger.info(f" Missing injection deny: {last_line_json}") + return False - # Perhaps the command was instrumented or could be skipped by its arguments. Checking - elif _get_command_props_values(command_desc, command_args) is True: - if last_line_json["msg"] in ["error when parsing", "skipping"] and last_line_json["error"].startswith( - "skipping due to ignore rules for language" - ): - logger.info(f" Command {command_args} was skipped by ignore arguments") - return True - - logger.info(f" command {command_args} is found but it was instrumented!") - return False logger.info(f" Command {command} was NOT FOUND") raise ValueError(f"Command {command} was NOT FOUND") @@ -54,52 +58,13 @@ def _parse_command(command): if "=" in com: command_args.remove(com) continue - return com, command_args - - -def _get_command_props_values(command_instrumentation_desc, command_args_check): - """ Search into command_instrumentation_desc (lines related with the command on the log file) - The line that contains the command with args should be like this (example for java -help): - { - "level":"debug", - "ts":1, - "caller":"xx", - "msg":"props values", - "props":{ - "Env":"", - "Service":"", - "Version":"", - "ProcessProps":{ - "Path":"/usr/bin/java", - "Args":[ - "java", - "-help" - ] - }, - "ContainerProps":{ - "Labels":null, - "Name":"", - "ShortName":"", - "Tag":"" - } - } - } - """ - for line in command_instrumentation_desc: - if "props values" in line: - line_json = json.loads(line) - command_log_args = line_json["props"]["ProcessProps"]["Args"] - command_compared_result = set(command_log_args) & set(command_args_check) - is_same_command = len(command_log_args) == len(command_args_check) and len(command_compared_result) == len( - command_args_check - ) + return os.path.basename(com), command_args - return is_same_command - return False + return None, None def _get_commands_from_log_file(log_local_path, line_filter): - """ From instrumentation log file, extract all commands parsed by dd-injection (the log level should be DEBUG) """ + """From instrumentation log file, extract all commands parsed by dd-injection (the log level should be DEBUG)""" store_as_command = False command_lines = [] diff --git a/utils/onboarding/wait_for_tcp_port.py b/utils/onboarding/wait_for_tcp_port.py index 0cd2d3cb07a..adbf44e48df 100644 --- a/utils/onboarding/wait_for_tcp_port.py +++ b/utils/onboarding/wait_for_tcp_port.py @@ -1,5 +1,4 @@ -""" -MIT License +"""MIT License Copyright (c) 2017 Michał Bultrowicz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -24,12 +23,15 @@ def wait_for_port(port: int, host: str = "localhost", timeout: float = 5.0): """Wait until a port starts accepting TCP connections. + Args: port: Port number. host: Host address on which the port should exist. timeout: In seconds. How long to wait before raising errors. + Raises: TimeoutError: The port isn't accepting connection after time specified in `timeout`. + """ start_time = time.perf_counter() while True: diff --git a/utils/onboarding/weblog_interface.py b/utils/onboarding/weblog_interface.py index 2855b0bf320..84e4b0e1f80 100644 --- a/utils/onboarding/weblog_interface.py +++ b/utils/onboarding/weblog_interface.py @@ -13,7 +13,7 @@ def make_get_request(app_url): "x-datadog-parent-id": generated_uuid, "x-datadog-sampling-priority": "2", }, - timeout=10, + timeout=15, ) return generated_uuid @@ -28,13 +28,14 @@ def warmup_weblog(app_url): def make_internal_get_request(stdin_file, vm_port): - """ This method is exclusively for testing through KrunVm microVM. - It is used to make a request to the weblog application inside the VM, using stdin file""" + """Exclusively for testing through KrunVm microVM. + It is used to make a request to the weblog application inside the VM, using stdin file + """ generated_uuid = str(randint(1, 100000000000000000)) timeout = 80 script_to_run = f"""#!/bin/bash -echo "Requesting weblog..." +echo "Requesting weblog..." URL="http://localhost:{vm_port}/" TIMEOUT={timeout} TRACE_ID={generated_uuid} @@ -74,3 +75,25 @@ def make_internal_get_request(stdin_file, vm_port): raise TimeoutError("Timed out waiting for weblog ready") return generated_uuid + + +def get_child_pids(virtual_machine) -> str: + vm_ip = virtual_machine.get_ip() + vm_port = virtual_machine.deffault_open_port + url = f"http://{vm_ip}:{vm_port}/child_pids" + return requests.get(url, timeout=60).text + + +def get_zombies(virtual_machine) -> str: + vm_ip = virtual_machine.get_ip() + vm_port = virtual_machine.deffault_open_port + url = f"http://{vm_ip}:{vm_port}/zombies" + return requests.get(url, timeout=60).text + + +def fork_and_crash(virtual_machine) -> str: + vm_ip = virtual_machine.get_ip() + vm_port = virtual_machine.deffault_open_port + url = f"http://{vm_ip}:{vm_port}/fork_and_crash" + # The timeout is high because coredump is triggered in some configs and takes a long time to complete + return requests.get(url, timeout=600).text diff --git a/utils/otel_validators/__init__.py b/utils/otel_validators/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/otel_validators/validator_log.py b/utils/otel_validators/validator_log.py index 42839798aa1..d039ced0187 100644 --- a/utils/otel_validators/validator_log.py +++ b/utils/otel_validators/validator_log.py @@ -2,7 +2,7 @@ def validate_log(log: dict, rid: str, otel_source: str) -> dict: - """ Validates the JSON logs from backend and returns the OTel log trace attributes """ + """Validates the JSON logs from backend and returns the OTel log trace attributes""" assert log["type"] == "log" expected_attributes_tags = [ "datadog.submission_auth:api_key", @@ -13,11 +13,11 @@ def validate_log(log: dict, rid: str, otel_source: str) -> dict: "source:otlp_log_ingestion", ] assert expected_attributes_tags <= log["attributes"]["tags"] - expected_attributes_attributes = { - "http": {"request": {"headers": {"user-agent": f"system_tests rid/{rid}"}}, "method": "GET"}, - "status": "info", - } - assert expected_attributes_attributes.items() <= log["attributes"]["attributes"].items() + + assert log["attributes"]["attributes"]["http"]["request"]["headers"]["user-agent"] == f"system_tests rid/{rid}" + assert log["attributes"]["attributes"]["http"]["method"] == "GET" + assert log["attributes"]["attributes"].get("status") == "info" or log["attributes"].get("status") == "info" + return log["attributes"]["attributes"]["otel"] @@ -28,4 +28,4 @@ def validate_log_trace_correlation(otel_log_trace_attrs: dict, trace: dict): span = item[1] assert otel_log_trace_attrs["trace_id"] == span["meta"]["otel.trace_id"] assert int(otel_log_trace_attrs["span_id"], 16) == int(span["span_id"]) - assert otel_log_trace_attrs["severity_number"] == "9" + assert str(otel_log_trace_attrs["severity_number"]) == "9" diff --git a/utils/otel_validators/validator_metric.py b/utils/otel_validators/validator_metric.py index 2866d68a19b..76f544029e6 100644 --- a/utils/otel_validators/validator_metric.py +++ b/utils/otel_validators/validator_metric.py @@ -2,10 +2,9 @@ import dictdiffer + # Validates the JSON logs from backend and returns the OTel log trace attributes -def validate_metrics( - metrics_1: list[dict], metrics_2: list[dict], metrics_source1: str, metrics_source2: str, -): +def validate_metrics(metrics_1: list[dict], metrics_2: list[dict], metrics_source1: str, metrics_source2: str): diff = list(dictdiffer.diff(metrics_1[0], metrics_2[0])) assert len(diff) == 0, f"Diff between count metrics from {metrics_source1} vs. from {metrics_source2}: {diff}" validate_example_counter(metrics_1[0]) diff --git a/utils/otel_validators/validator_trace.py b/utils/otel_validators/validator_trace.py index 11c1456aae2..6d485bad9e0 100644 --- a/utils/otel_validators/validator_trace.py +++ b/utils/otel_validators/validator_trace.py @@ -4,18 +4,19 @@ import dictdiffer from utils.tools import logger + # Validates traces from Agent, Collector and Backend intake OTLP ingestion paths are consistent def validate_all_traces( - traces_agent: list[dict], traces_intake: list[dict], traces_collector: list[dict], use_128_bits_trace_id: bool + traces_agent: list[dict], traces_intake: list[dict], traces_collector: list[dict], *, use_128_bits_trace_id: bool ): - spans_agent = validate_trace(traces_agent, use_128_bits_trace_id) - spans_intake = validate_trace(traces_intake, use_128_bits_trace_id) - spans_collector = validate_trace(traces_collector, use_128_bits_trace_id) + spans_agent = validate_trace(traces_agent, use_128_bits_trace_id=use_128_bits_trace_id) + spans_intake = validate_trace(traces_intake, use_128_bits_trace_id=use_128_bits_trace_id) + spans_collector = validate_trace(traces_collector, use_128_bits_trace_id=use_128_bits_trace_id) validate_spans_from_all_paths(spans_agent, spans_intake, spans_collector) # Validates fields that we know the values upfront for one single trace from an OTLP ingestion path -def validate_trace(traces: list[dict], use_128_bits_trace_id: bool) -> tuple: +def validate_trace(traces: list[dict], *, use_128_bits_trace_id: bool) -> tuple: server_span = None message_span = None for trace in traces: @@ -23,20 +24,20 @@ def validate_trace(traces: list[dict], use_128_bits_trace_id: bool) -> tuple: assert len(spans) == 1 for item in spans.items(): span = item[1] - validate_common_tags(span, use_128_bits_trace_id) + validate_common_tags(span, use_128_bits_trace_id=use_128_bits_trace_id) if span["type"] == "web": server_span = span elif span["type"] == "custom": message_span = span else: - raise Exception("Unexpected span ", span) + raise ValueError("Unexpected span ", span) validate_server_span(server_span) validate_message_span(message_span) validate_span_link(server_span, message_span) return (server_span, message_span) -def validate_common_tags(span: dict, use_128_bits_trace_id: bool): +def validate_common_tags(span: dict, *, use_128_bits_trace_id: bool): assert span["parent_id"] == "0" assert span["service"] == "otel-system-tests-spring-boot" expected_meta = { @@ -45,10 +46,10 @@ def validate_common_tags(span: dict, use_128_bits_trace_id: bool): "otel.library.name": "com.datadoghq.springbootnative", } assert expected_meta.items() <= span["meta"].items() - validate_trace_id(span, use_128_bits_trace_id) + validate_trace_id(span, use_128_bits_trace_id=use_128_bits_trace_id) -def validate_trace_id(span: dict, use_128_bits_trace_id: bool): +def validate_trace_id(span: dict, *, use_128_bits_trace_id: bool): dd_trace_id = int(span["trace_id"], base=10) otel_trace_id = int(span["meta"]["otel.trace_id"], base=16) if use_128_bits_trace_id: diff --git a/utils/parametric/_library_client.py b/utils/parametric/_library_client.py index 85012243b5c..1e033675bb3 100644 --- a/utils/parametric/_library_client.py +++ b/utils/parametric/_library_client.py @@ -1,15 +1,26 @@ # pylint: disable=E1101 +# pylint: disable=too-many-lines import contextlib import time import urllib.parse -from typing import Generator, List, Optional, Tuple, TypedDict, Union, Dict +from typing import TypedDict +from collections.abc import Generator -import grpc +from docker.models.containers import Container +import pytest +from _pytest.outcomes import Failed import requests +from opentelemetry.trace import SpanKind, StatusCode +from utils import context -from utils.parametric.protos import apm_test_client_pb2 as pb -from utils.parametric.protos import apm_test_client_pb2_grpc -from utils.parametric.spec.otel_trace import OtelSpanContext, convert_to_proto +from utils.parametric.spec.otel_trace import OtelSpanContext +from utils.tools import logger + + +def _fail(message): + """Used to mak a test as failed""" + logger.error(message) + raise Failed(message, pytrace=False) from None class StartSpanResponse(TypedDict): @@ -23,132 +34,21 @@ class SpanResponse(TypedDict): class Link(TypedDict): - parent_id: int # 0 to extract from headers + parent_id: int attributes: dict - http_headers: List[Tuple[str, str]] - - -class APMLibraryClient: - def trace_start_span( - self, - name: str, - service: str, - resource: str, - parent_id: int, - typestr: str, - origin: str, - http_headers: List[Tuple[str, str]], - links: List[Link], - tags: List[Tuple[str, str]], - ) -> StartSpanResponse: - raise NotImplementedError - - def otel_trace_start_span( - self, - name: str, - timestamp: int, - span_kind: int, - parent_id: int, - links: List[Link], - http_headers: List[Tuple[str, str]], - attributes: dict = None, - ) -> StartSpanResponse: - raise NotImplementedError - - def current_span(self) -> Union[SpanResponse, None]: - raise NotImplementedError - - def finish_span(self, span_id: int) -> None: - raise NotImplementedError - - def otel_current_span(self) -> Union[SpanResponse, None]: - raise NotImplementedError - - def otel_get_attribute(self, span_id: int, key: str): - raise NotImplementedError - - def otel_get_name(self, span_id: int): - raise NotImplementedError - - def otel_end_span(self, span_id: int, timestamp: int) -> None: - raise NotImplementedError - - def otel_get_links(self, span_id: int) -> List[Link]: - raise NotImplementedError - - def otel_set_attributes(self, span_id: int, attributes: dict) -> None: - raise NotImplementedError - - def otel_set_name(self, span_id: int, name: str) -> None: - raise NotImplementedError - def otel_set_status(self, span_id: int, code: int, description: str) -> None: - raise NotImplementedError - def otel_add_event(self, span_id: int, name: str, timestamp: int, attributes: dict) -> None: - raise NotImplementedError - - def otel_record_exception(self, span_id: int, message: str, attributes: dict) -> None: - raise NotImplementedError - - def otel_is_recording(self, span_id: int) -> bool: - raise NotImplementedError - - def otel_get_span_context(self, span_id: int): - raise NotImplementedError - - def span_add_link( - self, span_id: int, parent_id: int, attributes: dict, http_headers: List[Tuple[str, str]] = None - ) -> None: - raise NotImplementedError - - def span_set_resource(self, span_id: int, resource: str) -> None: - raise NotImplementedError - - def span_set_meta(self, span_id: int, key: str, value) -> None: - raise NotImplementedError - - def span_set_metric(self, span_id: int, key: str, value: float) -> None: - raise NotImplementedError - - def span_set_error(self, span_id: int, typestr: str, message: str, stack: str) -> None: - raise NotImplementedError - - def span_get_name(self, span_id: int): - raise NotImplementedError - - def span_get_resource(self, span_id: int): - raise NotImplementedError - - def span_get_meta(self, span_id: int, key: str): - raise NotImplementedError - - def span_get_metric(self, span_id: int, key: str): - raise NotImplementedError - - def trace_inject_headers(self, span_id) -> List[Tuple[str, str]]: - raise NotImplementedError - - def trace_flush(self) -> None: - raise NotImplementedError - - def trace_stop(self) -> None: - raise NotImplementedError - - def otel_flush(self, timeout: int) -> bool: - raise NotImplementedError - - def http_request(self, method: str, url: str, headers: List[Tuple[str, str]]) -> None: - raise NotImplementedError - - def get_tracer_config(self) -> Dict[str, Optional[str]]: - raise NotImplementedError +class Event(TypedDict): + time_unix_nano: int + name: str + attributes: dict -class APMLibraryClientHTTP(APMLibraryClient): - def __init__(self, url: str, timeout: int): +class APMLibraryClient: + def __init__(self, url: str, timeout: int, container: Container): self._base_url = url self._session = requests.Session() + self.container = container # wait for server to start self._wait(timeout) @@ -157,30 +57,76 @@ def _wait(self, timeout): delay = 0.01 for _ in range(int(timeout / delay)): try: - resp = self._session.get(self._url("/non-existent-endpoint-to-ping-until-the-server-starts")) - if resp.status_code == 404: + if self.is_alive(): break except Exception: - pass + if self.container.status != "running": + self._print_logs() + message = f"Container {self.container.name} status is {self.container.status}. Please check logs." + _fail(message) time.sleep(delay) else: - raise RuntimeError(f"Timeout of {timeout} seconds exceeded waiting for HTTP server to start") + self._print_logs() + message = f"Timeout of {timeout} seconds exceeded waiting for HTTP server to start. Please check logs." + _fail(message) + + def is_alive(self) -> bool: + self.container.reload() + return ( + self.container.status == "running" + and self._session.get(self._url("/non-existent-endpoint-to-ping-until-the-server-starts")).status_code + == 404 + ) + + def _print_logs(self): + try: + logs = self.container.logs().decode("utf-8") + logger.debug(f"Logs from container {self.container.name}:\n\n{logs}") + except Exception: + logger.error(f"Failed to get logs from container {self.container.name}") def _url(self, path: str) -> str: return urllib.parse.urljoin(self._base_url, path) + def crash(self) -> None: + try: + self._session.get(self._url("/trace/crash")) + except: + logger.info("Expected exception when calling /trace/crash") + + def container_exec_run(self, command: str) -> tuple[bool, str]: + try: + code, (stdout, _) = self.container.exec_run(command, demux=True) + if code is None: + success = False + message = "Exit code from command in the parametric app container is None" + elif stdout is None: + success = False + message = "Stdout from command in the parametric app container is None" + else: + success = True + message = stdout.decode() + except BaseException: + return False, "Encountered an issue running command in the parametric app container" + + return success, message + def trace_start_span( self, name: str, - service: str, - resource: str, - parent_id: int, - typestr: str, - origin: str, - http_headers: Optional[List[Tuple[str, str]]], - links: Optional[List[Link]], - tags: Optional[List[Tuple[str, str]]], + service: str | None = None, + resource: str | None = None, + parent_id: str | None = None, + typestr: str | None = None, + tags: list[tuple[str, str]] | None = None, ): + if context.library == "cpp": + # TODO: Update the cpp parametric app to accept null values for unset parameters + service = service or "" + resource = resource or "" + parent_id = parent_id or 0 + typestr = typestr or "" + resp = self._session.post( self._url("/trace/span/start"), json={ @@ -189,32 +135,42 @@ def trace_start_span( "resource": resource, "parent_id": parent_id, "type": typestr, - "origin": origin, - "http_headers": http_headers, - "links": links, - "span_tags": tags, + "span_tags": tags if tags is not None else [], }, ) + + if resp.status_code != 200: + raise pytest.fail(f"Failed to start span: {resp.text}", pytrace=False) + resp_json = resp.json() - return StartSpanResponse(span_id=resp_json["span_id"], trace_id=resp_json["trace_id"],) + return StartSpanResponse(span_id=resp_json["span_id"], trace_id=resp_json["trace_id"]) - def current_span(self) -> Union[SpanResponse, None]: + def current_span(self) -> SpanResponse | None: resp_json = self._session.get(self._url("/trace/span/current")).json() if not resp_json: return None return SpanResponse(span_id=resp_json["span_id"], trace_id=resp_json["trace_id"]) def finish_span(self, span_id: int) -> None: - self._session.post(self._url("/trace/span/finish"), json={"span_id": span_id,}) + self._session.post(self._url("/trace/span/finish"), json={"span_id": span_id}) def span_set_resource(self, span_id: int, resource: str) -> None: - self._session.post(self._url("/trace/span/set_resource"), json={"span_id": span_id, "resource": resource,}) + self._session.post(self._url("/trace/span/set_resource"), json={"span_id": span_id, "resource": resource}) def span_set_meta(self, span_id: int, key: str, value) -> None: - self._session.post(self._url("/trace/span/set_meta"), json={"span_id": span_id, "key": key, "value": value,}) + self._session.post(self._url("/trace/span/set_meta"), json={"span_id": span_id, "key": key, "value": value}) + + def span_set_baggage(self, span_id: int, key: str, value: str) -> None: + self._session.post(self._url("/trace/span/set_baggage"), json={"span_id": span_id, "key": key, "value": value}) + + def span_remove_baggage(self, span_id: int, key: str) -> None: + self._session.post(self._url("/trace/span/remove_baggage"), json={"span_id": span_id, "key": key}) + + def span_remove_all_baggage(self, span_id: int) -> None: + self._session.post(self._url("/trace/span/remove_all_baggage"), json={"span_id": span_id}) def span_set_metric(self, span_id: int, key: str, value: float) -> None: - self._session.post(self._url("/trace/span/set_metric"), json={"span_id": span_id, "key": key, "value": value,}) + self._session.post(self._url("/trace/span/set_metric"), json={"span_id": span_id, "key": key, "value": value}) def span_set_error(self, span_id: int, typestr: str, message: str, stack: str) -> None: self._session.post( @@ -222,98 +178,83 @@ def span_set_error(self, span_id: int, typestr: str, message: str, stack: str) - json={"span_id": span_id, "type": typestr, "message": message, "stack": stack}, ) - def span_add_link( - self, span_id: int, parent_id: int, attributes: dict = None, http_headers: List[Tuple[str, str]] = None - ): + def span_add_link(self, span_id: int, parent_id: int, attributes: dict | None = None): self._session.post( self._url("/trace/span/add_link"), - json={ - "span_id": span_id, - "parent_id": parent_id, - "attributes": attributes or {}, - "http_headers": http_headers or [], - }, + json={"span_id": span_id, "parent_id": parent_id, "attributes": attributes or {}}, ) - def span_get_meta(self, span_id: int, key: str): - resp = self._session.post(self._url("/trace/span/get_meta"), json={"span_id": span_id, "key": key,}) - return resp.json()["value"] + def span_add_event(self, span_id: int, name: str, timestamp: int, attributes: dict | None = None): + self._session.post( + self._url("/trace/span/add_event"), + json={"span_id": span_id, "name": name, "timestamp": timestamp, "attributes": attributes or {}}, + ) - def span_get_metric(self, span_id: int, key: str): - resp = self._session.post(self._url("/trace/span/get_metric"), json={"span_id": span_id, "key": key,}) - return resp.json()["value"] + def span_get_baggage(self, span_id: int, key: str) -> str: + resp = self._session.get(self._url("/trace/span/get_baggage"), json={"span_id": span_id, "key": key}) + resp = resp.json() + return resp["baggage"] - def span_get_resource(self, span_id: int): - resp = self._session.post(self._url("/trace/span/get_resource"), json={"span_id": span_id,}) - return resp.json()["resource"] + def span_get_all_baggage(self, span_id: int) -> dict: + resp = self._session.get(self._url("/trace/span/get_all_baggage"), json={"span_id": span_id}) + resp = resp.json() + return resp["baggage"] def trace_inject_headers(self, span_id): - resp = self._session.post(self._url("/trace/span/inject_headers"), json={"span_id": span_id},) - # todo: translate json into list within list + resp = self._session.post(self._url("/trace/span/inject_headers"), json={"span_id": span_id}) + # TODO: translate json into list within list # so server.xx do not have to return resp.json()["http_headers"] - def trace_flush(self) -> None: - self._session.post(self._url("/trace/span/flush"), json={}) - self._session.post(self._url("/trace/stats/flush"), json={}) + def trace_extract_headers(self, http_headers: list[tuple[str, str]]): + resp = self._session.post(self._url("/trace/span/extract_headers"), json={"http_headers": http_headers}) + return resp.json()["span_id"] + + def trace_flush(self) -> bool: + return ( + self._session.post(self._url("/trace/span/flush"), json={}).status_code < 300 + and self._session.post(self._url("/trace/stats/flush"), json={}).status_code < 300 + ) def otel_trace_start_span( self, name: str, - timestamp: int, - span_kind: int, - parent_id: int, - links: List[Link], - http_headers: List[Tuple[str, str]], - attributes: dict = None, + timestamp: int | None, + span_kind: SpanKind | None, + parent_id: int | None, + links: list[Link] | None, + events: list[Event] | None, + attributes: dict | None, ) -> StartSpanResponse: resp = self._session.post( self._url("/trace/otel/start_span"), json={ "name": name, "timestamp": timestamp, - "span_kind": span_kind, "parent_id": parent_id, - "links": links, - "http_headers": http_headers, + "span_kind": span_kind.value if span_kind is not None else None, + "links": links or [], + "events": events or [], "attributes": attributes or {}, }, ).json() + # TODO: Some http endpoints return span_id and trace_id as strings (ex: dotnet), some as uint64 (ex: go) + # and others with bignum trace_ids and uint64 span_ids (ex: python). We should standardize this. return StartSpanResponse(span_id=resp["span_id"], trace_id=resp["trace_id"]) - def otel_current_span(self) -> Union[SpanResponse, None]: - resp = self._session.get(self._url("/trace/otel/current_span"), json={}) - if not resp: - return None - - resp_json = resp.json() - return SpanResponse(span_id=resp_json["span_id"], trace_id=resp_json["trace_id"]) - - def otel_get_attribute(self, span_id: int, key: str): - resp = self._session.post(self._url("/trace/otel/get_attribute"), json={"span_id": span_id, "key": key,}) - return resp.json()["value"] - - def otel_get_name(self, span_id: int): - resp = self._session.post(self._url("/trace/otel/get_name"), json={"span_id": span_id,}) - return resp.json()["name"] - - def otel_end_span(self, span_id: int, timestamp: int) -> None: + def otel_end_span(self, span_id: int, timestamp: int | None) -> None: self._session.post(self._url("/trace/otel/end_span"), json={"id": span_id, "timestamp": timestamp}) - def otel_get_links(self, span_id: int): - resp_json = self._session.post(self._url("/trace/otel/get_links"), json={"span_id": span_id}).json() - - return resp_json["links"] - def otel_set_attributes(self, span_id: int, attributes) -> None: self._session.post(self._url("/trace/otel/set_attributes"), json={"span_id": span_id, "attributes": attributes}) def otel_set_name(self, span_id: int, name: str) -> None: self._session.post(self._url("/trace/otel/set_name"), json={"span_id": span_id, "name": name}) - def otel_set_status(self, span_id: int, code: int, description: str) -> None: + def otel_set_status(self, span_id: int, code: StatusCode, description: str) -> None: self._session.post( - self._url("/trace/otel/set_status"), json={"span_id": span_id, "code": code, "description": description} + self._url("/trace/otel/set_status"), + json={"span_id": span_id, "code": code.name, "description": description}, ) def otel_add_event(self, span_id: int, name: str, timestamp: int, attributes) -> None: @@ -346,14 +287,14 @@ def otel_flush(self, timeout: int) -> bool: resp = self._session.post(self._url("/trace/otel/flush"), json={"seconds": timeout}).json() return resp["success"] - def http_client_request(self, method: str, url: str, headers: List[Tuple[str, str]], body: bytes) -> int: + def otel_set_baggage(self, span_id: int, key: str, value: str) -> None: resp = self._session.post( - self._url("/http/client/request"), - json={"method": method, "url": url, "headers": headers or [], "body": body.decode()}, - ).json() - return resp + self._url("/trace/otel/otel_set_baggage"), json={"span_id": span_id, "key": key, "value": value} + ) + resp = resp.json() + return resp["value"] - def get_tracer_config(self) -> Dict[str, Optional[str]]: + def config(self) -> dict[str, str | None]: resp = self._session.get(self._url("/trace/config")).json() config_dict = resp["config"] return { @@ -369,11 +310,23 @@ def get_tracer_config(self) -> Dict[str, Optional[str]]: "dd_trace_sample_ignore_parent": config_dict.get("dd_trace_sample_ignore_parent", None), "dd_env": config_dict.get("dd_env", None), "dd_version": config_dict.get("dd_version", None), + "dd_trace_agent_url": config_dict.get("dd_trace_agent_url", None), + "dd_trace_rate_limit": config_dict.get("dd_trace_rate_limit", None), + "dd_dogstatsd_host": config_dict.get("dd_dogstatsd_host", None), + "dd_dogstatsd_port": config_dict.get("dd_dogstatsd_port", None), } + def otel_current_span(self) -> SpanResponse | None: + resp = self._session.get(self._url("/trace/otel/current_span"), json={}) + if not resp: + return None + + resp_json = resp.json() + return SpanResponse(span_id=resp_json["span_id"], trace_id=resp_json["trace_id"]) + class _TestSpan: - def __init__(self, client: APMLibraryClient, span_id: int, trace_id: int = 0, parent_id: int = 0): + def __init__(self, client: APMLibraryClient, span_id: int, trace_id: int): self._client = client self.span_id = span_id self.trace_id = trace_id @@ -387,30 +340,33 @@ def set_meta(self, key: str, val): def set_metric(self, key: str, val: float): self._client.span_set_metric(self.span_id, key, val) - def set_error(self, typestr: str = "", message: str = "", stack: str = ""): - self._client.span_set_error(self.span_id, typestr, message, stack) + def set_baggage(self, key: str, val: str): + self._client.span_set_baggage(self.span_id, key, val) + + def get_baggage(self, key: str): + return self._client.span_get_baggage(self.span_id, key) - def add_link(self, parent_id: int, attributes: dict = None, http_headers: List[Tuple[str, str]] = None): - self._client.span_add_link(self.span_id, parent_id, attributes, http_headers) + def get_all_baggage(self): + return self._client.span_get_all_baggage(self.span_id) - def get_name(self): - return self._client.span_get_name(self.span_id) + def remove_baggage(self, key: str): + self._client.span_remove_baggage(self.span_id, key) - def get_resource(self): - return self._client.span_get_resource(self.span_id) + def remove_all_baggage(self): + self._client.span_remove_all_baggage(self.span_id) - def get_meta(self, key: str): - return self._client.span_get_meta(self.span_id, key) + def set_error(self, typestr: str = "", message: str = "", stack: str = ""): + self._client.span_set_error(self.span_id, typestr, message, stack) - def get_metric(self, key: str): - return self._client.span_get_metric(self.span_id, key) + def add_link(self, parent_id: int, attributes: dict | None = None): + self._client.span_add_link(self.span_id, parent_id, attributes) def finish(self): self._client.finish_span(self.span_id) class _TestOtelSpan: - def __init__(self, client: APMLibraryClient, span_id: int, trace_id: int = 0): + def __init__(self, client: APMLibraryClient, span_id: int, trace_id: int): self._client = client self.span_id = span_id self.trace_id = trace_id @@ -426,16 +382,16 @@ def set_attribute(self, key, value): def set_name(self, name): self._client.otel_set_name(self.span_id, name) - def set_status(self, code, description): + def set_status(self, code: StatusCode, description): self._client.otel_set_status(self.span_id, code, description) - def add_event(self, name: str, timestamp: Optional[int] = None, attributes: Optional[dict] = None): + def add_event(self, name: str, timestamp: int | None = None, attributes: dict | None = None): self._client.otel_add_event(self.span_id, name, timestamp, attributes) - def record_exception(self, message: str, attributes: Optional[dict] = None): + def record_exception(self, message: str, attributes: dict | None = None): self._client.otel_record_exception(self.span_id, message, attributes) - def end_span(self, timestamp: int = 0): + def end_span(self, timestamp: int | None = None): self._client.otel_end_span(self.span_id, timestamp) def is_recording(self) -> bool: @@ -444,224 +400,8 @@ def is_recording(self) -> bool: def span_context(self) -> OtelSpanContext: return self._client.otel_get_span_context(self.span_id) - # SDK methods - - def get_attribute(self, key: str): - return self._client.otel_get_attribute(self.span_id, key) - - def get_name(self): - return self._client.otel_get_name(self.span_id) - - def get_links(self): - return self._client.otel_get_links(self.span_id) - - -class APMLibraryClientGRPC: - def __init__(self, url: str, timeout: int): - channel = grpc.insecure_channel(url) - grpc.channel_ready_future(channel).result(timeout=timeout) - client = apm_test_client_pb2_grpc.APMClientStub(channel) - self._client = client - - def __enter__(self) -> "APMLibrary": - return self - - def trace_start_span( - self, - name: str, - service: str, - resource: str, - parent_id: int, - typestr: str, - origin: str, - http_headers: List[Tuple[str, str]], - links: List[Link], - tags: List[Tuple[str, str]], - ): - distributed_message = pb.DistributedHTTPHeaders() - for key, value in http_headers: - distributed_message.http_headers.append(pb.HeaderTuple(key=key, value=value)) - - pb_tags = [] - for key, value in tags: - pb_tags.append(pb.HeaderTuple(key=key, value=value)) - - pb_links = [] - for link in links: - pb_link = pb.SpanLink(attributes=convert_to_proto(link.get("attributes"))) - if link.get("parent_id") and link.get("http_headers"): - raise ValueError("Link cannot have both parent_id and http_headers") - if link.get("parent_id"): - pb_link.parent_id = link["parent_id"] - else: - for key, value in link["http_headers"]: - pb_link.http_headers.http_headers.append(pb.HeaderTuple(key=key, value=value)) - - pb_links.append(pb_link) - - resp = self._client.StartSpan( - pb.StartSpanArgs( - name=name, - service=service, - resource=resource, - parent_id=parent_id, - type=typestr, - origin=origin, - http_headers=distributed_message, - span_links=pb_links, - span_tags=pb_tags, - ) - ) - return { - "span_id": resp.span_id, - "trace_id": resp.trace_id, - } - - def otel_trace_start_span( - self, - name: str, - timestamp: int, - span_kind: int, - parent_id: int, - links: List[Link], - http_headers: List[Tuple[str, str]], - attributes: dict = None, - ): - distributed_message = pb.DistributedHTTPHeaders() - for key, value in http_headers: - distributed_message.http_headers.append(pb.HeaderTuple(key=key, value=value)) - - pb_links = [] - for link in links: - pb_link = pb.SpanLink(attributes=convert_to_proto(link.get("attributes"))) - if link.get("parent_id") and link.get("http_headers"): - raise ValueError("Link cannot have both parent_id and http_headers") - if link.get("parent_id") is not None: - pb_link.parent_id = link["parent_id"] - else: - for key, value in link["http_headers"]: - pb_link.http_headers.http_headers.append(pb.HeaderTuple(key=key, value=value)) - pb_links.append(pb_link) - - resp = self._client.OtelStartSpan( - pb.OtelStartSpanArgs( - name=name, - timestamp=timestamp, - span_kind=span_kind, - parent_id=parent_id, - span_links=pb_links, - attributes=convert_to_proto(attributes), - http_headers=distributed_message, - ) - ) - return { - "span_id": resp.span_id, - "trace_id": resp.trace_id, - } - - def trace_flush(self): - self._client.FlushSpans(pb.FlushSpansArgs()) - self._client.FlushTraceStats(pb.FlushTraceStatsArgs()) - - def trace_inject_headers(self, span_id) -> List[Tuple[str, str]]: - resp = self._client.InjectHeaders(pb.InjectHeadersArgs(span_id=span_id,)) - return [(header_tuple.key, header_tuple.value) for header_tuple in resp.http_headers.http_headers] - - def stop(self): - return self._client.StopTracer(pb.StopTracerArgs()) - - def span_set_meta(self, span_id: int, key: str, val: str): - self._client.SpanSetMeta(pb.SpanSetMetaArgs(span_id=span_id, key=key, value=val,)) - - def span_set_metric(self, span_id: int, key: str, val: float): - self._client.SpanSetMetric(pb.SpanSetMetricArgs(span_id=span_id, key=key, value=val,)) - - def span_set_error(self, span_id: int, typestr: str = "", message: str = "", stack: str = ""): - self._client.SpanSetError(pb.SpanSetErrorArgs(span_id=span_id, type=typestr, message=message, stack=stack)) - - def span_add_link( - self, span_id: int, parent_id: int, attributes: dict, http_headers: List[Tuple[str, str]] - ) -> None: - pb_link = pb.SpanLink(attributes=convert_to_proto(attributes)) - if parent_id > 0: - pb_link.parent_id = parent_id - elif http_headers: - for key, value in http_headers: - pb_link.http_headers.http_headers.append(pb.HeaderTuple(key=key, value=value)) - else: - raise ValueError("Link must have either parent_id or http_headers") - - self._client.SpanAddLink(pb.SpanAddLinkArgs(span_id=span_id, span_link=pb_link,)) - - def finish_span(self, span_id: int): - self._client.FinishSpan(pb.FinishSpanArgs(id=span_id)) - - def http_client_request(self, method: str, url: str, headers: List[Tuple[str, str]], body: bytes) -> int: - hs = pb.DistributedHTTPHeaders() - for key, value in headers: - hs.http_headers.append(pb.HeaderTuple(key=key, value=value)) - - self._client.HTTPClientRequest(pb.HTTPRequestArgs(method=method, url=url, headers=hs, body=body,)) - - def otel_end_span(self, span_id: int, timestamp: int): - self._client.OtelEndSpan(pb.OtelEndSpanArgs(id=span_id, timestamp=timestamp)) - - def otel_set_attributes(self, span_id: int, attributes): - self._client.OtelSetAttributes( - pb.OtelSetAttributesArgs(span_id=span_id, attributes=convert_to_proto(attributes)) - ) - - def otel_set_name(self, span_id: int, name: str): - self._client.OtelSetName(pb.OtelSetNameArgs(span_id=span_id, name=name)) - - def otel_set_status(self, span_id: int, code: int, description: str): - self._client.OtelSetStatus(pb.OtelSetStatusArgs(span_id=span_id, code=code, description=description)) - - def otel_add_event(self, span_id: int, name: str, timestamp: int, attributes): - self._client.OtelAddEvent( - pb.OtelAddEventArgs( - span_id=span_id, name=name, timestamp=timestamp, attributes=convert_to_proto(attributes) - ) - ) - - def otel_record_exception(self, span_id: int, message: str, attributes): - self._client.OtelRecordException( - pb.OtelRecordExceptionArgs(span_id=span_id, message=message, attributes=convert_to_proto(attributes)) - ) - - def otel_is_recording(self, span_id: int) -> bool: - return self._client.OtelIsRecording(pb.OtelIsRecordingArgs(span_id=span_id)).is_recording - - def otel_get_span_context(self, span_id: int) -> OtelSpanContext: - sctx = self._client.OtelSpanContext(pb.OtelSpanContextArgs(span_id=span_id)) - return OtelSpanContext( - trace_id=sctx.trace_id, - span_id=sctx.span_id, - trace_flags=sctx.trace_flags, - trace_state=sctx.trace_state, - remote=sctx.remote, - ) - - def otel_flush(self, timeout: int) -> bool: - return self._client.OtelFlushSpans(pb.OtelFlushSpansArgs(seconds=timeout)).success - - def get_tracer_config(self) -> Dict[str, Optional[str]]: - resp = self._client.GetTraceConfig(pb.GetTraceConfigArgs()) - config_dict = resp.config - return { - "dd_service": config_dict.get("dd_service", None), - "dd_log_level": config_dict.get("dd_log_level", None), - "dd_trace_sample_rate": config_dict.get("dd_trace_sample_rate", None), - "dd_trace_enabled": config_dict.get("dd_trace_enabled", None), - "dd_runtime_metrics_enabled": config_dict.get("dd_runtime_metrics_enabled", None), - "dd_tags": config_dict.get("dd_tags", None), - "dd_trace_propagation_style": config_dict.get("dd_trace_propagation_style", None), - "dd_trace_debug": config_dict.get("dd_trace_debug", None), - "dd_trace_otel_enabled": config_dict.get("dd_trace_otel_enabled", None), - "dd_trace_sample_ignore_parent": config_dict.get("dd_trace_sample_ignore_parent", None), - "dd_env": config_dict.get("dd_env", None), - "dd_version": config_dict.get("dd_version", None), - } + def set_baggage(self, key: str, value: str): + self._client.otel_set_baggage(self.span_id, key, value) class APMLibrary: @@ -675,96 +415,105 @@ def __enter__(self) -> "APMLibrary": def __exit__(self, exc_type, exc_val, exc_tb): # Only attempt a flush if there was no exception raised. if exc_type is None: - self.flush() + self.dd_flush() + if self.lang != "cpp": + # C++ does not have an otel/flush endpoint + self.otel_flush(1) + + def crash(self) -> None: + self._client.crash() + + def container_exec_run(self, command: str) -> tuple[bool, str]: + return self._client.container_exec_run(command) @contextlib.contextmanager - def start_span( + def dd_start_span( self, name: str, - service: str = "", - resource: str = "", - parent_id: int = 0, - typestr: str = "", - origin: str = "", - http_headers: Optional[List[Tuple[str, str]]] = None, - links: Optional[List[Link]] = None, - tags: Optional[List[Tuple[str, str]]] = None, + service: str | None = None, + resource: str | None = None, + parent_id: str | None = None, + typestr: str | None = None, + tags: list[tuple[str, str]] | None = None, ) -> Generator[_TestSpan, None, None]: resp = self._client.trace_start_span( - name=name, - service=service, - resource=resource, - parent_id=parent_id, - typestr=typestr, - origin=origin, - http_headers=http_headers if http_headers is not None else [], - links=links if links is not None else [], - tags=tags if tags is not None else [], + name=name, service=service, resource=resource, parent_id=parent_id, typestr=typestr, tags=tags ) - span = _TestSpan(self._client, resp["span_id"]) + span = _TestSpan(self._client, resp["span_id"], resp["trace_id"]) yield span span.finish() + def dd_extract_headers_and_make_child_span(self, name, http_headers): + parent_id = self.dd_extract_headers(http_headers=http_headers) + return self.dd_start_span(name=name, parent_id=parent_id) + + def dd_make_child_span_and_get_headers(self, headers): + with self.dd_extract_headers_and_make_child_span("name", headers) as span: + headers = self.dd_inject_headers(span.span_id) + return {k.lower(): v for k, v in headers} + @contextlib.contextmanager def otel_start_span( self, name: str, - timestamp: int = 0, - span_kind: int = 0, - parent_id: int = 0, - links: Optional[List[Link]] = None, - attributes: dict = None, - http_headers: Optional[List[Tuple[str, str]]] = None, + timestamp: int | None = None, + span_kind: SpanKind | None = None, + parent_id: int | None = None, + links: list[Link] | None = None, + events: list[Event] | None = None, + attributes: dict | None = None, + *, + end_on_exit: bool = True, ) -> Generator[_TestOtelSpan, None, None]: resp = self._client.otel_trace_start_span( name=name, timestamp=timestamp, span_kind=span_kind, parent_id=parent_id, - links=links if links is not None else [], + links=links, + events=events if events is not None else [], attributes=attributes, - http_headers=http_headers if http_headers is not None else [], ) - span = _TestOtelSpan(self._client, resp["span_id"]) + span = _TestOtelSpan(self._client, resp["span_id"], resp["trace_id"]) yield span + if end_on_exit: + span.end_span() - return { - "span_id": resp["span_id"], - "trace_id": resp["trace_id"], - } - - def current_span(self) -> Union[_TestSpan, None]: - resp = self._client.current_span() - if resp is None: - return None - return _TestSpan(self._client, resp["span_id"], resp["trace_id"]) - - def flush(self): - self._client.trace_flush() + def dd_flush(self) -> bool: + return self._client.trace_flush() def otel_flush(self, timeout_sec: int) -> bool: return self._client.otel_flush(timeout_sec) - def otel_current_span(self) -> Union[_TestOtelSpan, None]: - resp = self._client.otel_current_span() - if resp is None: - return None - return _TestOtelSpan(self._client, resp["span_id"], resp["trace_id"]) - def otel_is_recording(self, span_id: int) -> bool: return self._client.otel_is_recording(span_id) - def inject_headers(self, span_id) -> List[Tuple[str, str]]: + def dd_inject_headers(self, span_id) -> list[tuple[str, str]]: return self._client.trace_inject_headers(span_id) - def http_client_request( - self, url: str, method: str = "GET", headers: List[Tuple[str, str]] = None, body: Optional[bytes] = b"", - ): - """Do an HTTP request with the given method and headers.""" - return self._client.http_client_request(method=method, url=url, headers=headers or [], body=body,) + def dd_extract_headers(self, http_headers: list[tuple[str, str]]) -> int: + return self._client.trace_extract_headers(http_headers) - def finish_span(self, span_id: int) -> None: - self._client.finish_span(span_id) + def otel_set_baggage(self, span_id: int, key: str, value: str): + return self._client.otel_set_baggage(span_id, key, value) + + def config(self) -> dict[str, str | None]: + return self._client.config() + + def dd_current_span(self) -> _TestSpan | None: + resp = self._client.current_span() + if resp is None: + return None + return _TestSpan(self._client, resp["span_id"], resp["trace_id"]) + + def otel_current_span(self) -> _TestOtelSpan | None: + resp = self._client.otel_current_span() + if resp is None: + return None + return _TestOtelSpan(self._client, resp["span_id"], resp["trace_id"]) - def get_tracer_config(self) -> Dict[str, Optional[str]]: - return self._client.get_tracer_config() + def is_alive(self) -> bool: + try: + return self._client.is_alive() + except Exception: + return False diff --git a/utils/parametric/generate_protos.ps1 b/utils/parametric/generate_protos.ps1 deleted file mode 100644 index ee955676261..00000000000 --- a/utils/parametric/generate_protos.ps1 +++ /dev/null @@ -1,8 +0,0 @@ -# Generate protobuf Python source files for the testing client. -# This test client is used to make requests to each of the language-specific -# grpc servers. -# Requires protoc to be installed on the host. - -python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. protos/apm_test_client.proto -# FIXME: the codegen doesn't generate the correct import path -Get-ChildItem ".\protos\*.py" | % { (Get-Content $_.FullName) -replace 'from protos','from utils.parametric.protos' | Set-Content $_.FullName } diff --git a/utils/parametric/generate_protos.sh b/utils/parametric/generate_protos.sh deleted file mode 100755 index f40ec8e0264..00000000000 --- a/utils/parametric/generate_protos.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -SEDOPTION=("-i") -if [[ "$OSTYPE" == "darwin"* ]]; then - SEDOPTION=("-i ''") -fi - -python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. protos/apm_test_client.proto -sed "${SEDOPTION[@]}" -e 's/from protos/from utils.parametric.protos/g' protos/*.py diff --git a/utils/parametric/headers.py b/utils/parametric/headers.py deleted file mode 100644 index 665010caa94..00000000000 --- a/utils/parametric/headers.py +++ /dev/null @@ -1,4 +0,0 @@ -def make_single_request_and_get_inject_headers(test_library, headers): - with test_library.start_span(name="name", service="service", resource="resource", http_headers=headers,) as span: - headers = test_library.inject_headers(span.span_id) - return {k.lower(): v for k, v in headers} diff --git a/utils/parametric/protos/apm_test_client.proto b/utils/parametric/protos/apm_test_client.proto deleted file mode 100644 index b1ab8c47dfc..00000000000 --- a/utils/parametric/protos/apm_test_client.proto +++ /dev/null @@ -1,336 +0,0 @@ -syntax = "proto3"; - -option java_package = "com.datadoghq.client"; -//option go_package = "./"; -option csharp_namespace = "ApmTestClient"; - -// Interface of APM clients to be used for shared testing. -service APMClient { - rpc StartSpan(StartSpanArgs) returns (StartSpanReturn) {} - rpc FinishSpan(FinishSpanArgs) returns (FinishSpanReturn) {} - rpc SpanGetCurrent(SpanGetCurrentArgs) returns (SpanGetCurrentReturn) {} - rpc SpanGetName(SpanGetNameArgs) returns (SpanGetNameReturn) {} - rpc SpanGetResource(SpanGetResourceArgs) returns (SpanGetResourceReturn) {} - rpc SpanGetMeta(SpanGetMetaArgs) returns (SpanGetMetaReturn) {} - rpc SpanGetMetric(SpanGetMetricArgs) returns (SpanGetMetricReturn) {} - rpc SpanSetMeta(SpanSetMetaArgs) returns (SpanSetMetaReturn) {} - rpc SpanSetMetric(SpanSetMetricArgs) returns (SpanSetMetricReturn) {} - rpc SpanSetError(SpanSetErrorArgs) returns (SpanSetErrorReturn) {} - rpc SpanSetResource(SpanSetResourceArgs) returns (SpanSetResourceReturn) {} - rpc SpanAddLink(SpanAddLinkArgs) returns (SpanAddLinkReturn) {} - rpc HTTPClientRequest(HTTPRequestArgs) returns (HTTPRequestReturn) {} - rpc HTTPServerRequest(HTTPRequestArgs) returns (HTTPRequestReturn) {} - rpc InjectHeaders(InjectHeadersArgs) returns (InjectHeadersReturn) {} - rpc FlushSpans(FlushSpansArgs) returns (FlushSpansReturn) {} - rpc FlushTraceStats(FlushTraceStatsArgs) returns (FlushTraceStatsReturn) {} - - rpc OtelStartSpan(OtelStartSpanArgs) returns (OtelStartSpanReturn) {} - rpc OtelEndSpan(OtelEndSpanArgs) returns (OtelEndSpanReturn) {} - rpc OtelAddEvent(OtelAddEventArgs) returns (OtelAddEventReturn) {} - rpc OtelRecordException(OtelRecordExceptionArgs) returns (OtelRecordExceptionReturn) {} - rpc OtelIsRecording(OtelIsRecordingArgs) returns (OtelIsRecordingReturn) {} - rpc OtelSpanContext(OtelSpanContextArgs) returns (OtelSpanContextReturn) {} - rpc OtelSpanGetCurrent(OtelSpanGetCurrentArgs) returns (OtelSpanGetCurrentReturn) {} - rpc OtelSetStatus(OtelSetStatusArgs) returns (OtelSetStatusReturn) {} - rpc OtelSetName(OtelSetNameArgs) returns (OtelSetNameReturn) {} - rpc OtelSetAttributes(OtelSetAttributesArgs) returns (OtelSetAttributesReturn) {} - rpc OtelFlushSpans(OtelFlushSpansArgs) returns (OtelFlushSpansReturn) {} - rpc OtelFlushTraceStats(OtelFlushTraceStatsArgs) returns (OtelFlushTraceStatsReturn) {} - rpc OtelGetAttribute(OtelGetAttributeArgs) returns (OtelGetAttributeReturn) {} - rpc OtelGetName(OtelGetNameArgs) returns (OtelGetNameReturn) {} - rpc OtelGetLinks(OtelGetLinksArgs) returns (OtelGetLinksReturn) {} - - rpc StopTracer(StopTracerArgs) returns (StopTracerReturn) {} - - rpc GetTraceConfig(GetTraceConfigArgs) returns (GetTraceConfigReturn) {} -} - -message GetTraceConfigArgs {} - -message GetTraceConfigReturn { - map config = 1; - -} - -message StartSpanArgs { - string name = 1; - optional string service = 2; - optional uint64 parent_id = 3; - optional string resource = 4; - optional string type = 5; - optional string origin = 6; - optional DistributedHTTPHeaders http_headers = 7; - repeated HeaderTuple span_tags = 8; - repeated SpanLink span_links = 9; -} - -message DistributedHTTPHeaders { - repeated HeaderTuple http_headers = 1; -} - -message SpanLink { - oneof from { - uint64 parent_id = 1; - DistributedHTTPHeaders http_headers = 2; - } - Attributes attributes = 3; -} - -message HeaderTuple { - string key = 1; - string value = 2; -} - -message StartSpanReturn { - uint64 span_id = 1; - uint64 trace_id = 2; -} - -message InjectHeadersArgs { - uint64 span_id = 1; -} - -message InjectHeadersReturn { - optional DistributedHTTPHeaders http_headers = 1; -} - -message FinishSpanArgs { - uint64 id = 1; -} -message FinishSpanReturn {} - -message SpanGetCurrentArgs {} -message SpanGetCurrentReturn { - uint64 span_id = 1; - uint64 trace_id = 2; -} - -message SpanGetNameArgs { - uint64 span_id = 1; -} -message SpanGetNameReturn { - string name = 1; -} - -message SpanGetResourceArgs { - uint64 span_id = 1; -} -message SpanGetResourceReturn { - string resource = 1; -} - -message SpanGetMetaArgs { - uint64 span_id = 1; - string key = 2; -} -message SpanGetMetaReturn { - AttrVal value = 1; -} - -message SpanGetMetricArgs { - uint64 span_id = 1; - string key = 2; -} -message SpanGetMetricReturn { - float value = 1; -} - -message SpanSetMetaArgs { - uint64 span_id = 1; - string key = 2; - string value = 3; -} -message SpanSetMetaReturn {} - - -message SpanSetMetricArgs { - uint64 span_id = 1; - string key = 2; - float value = 3; -} -message SpanSetMetricReturn {} - - -message SpanSetErrorArgs { - uint64 span_id = 1; - optional string type = 2; - optional string message = 3; - optional string stack = 4; -} -message SpanSetErrorReturn {} - -message SpanSetResourceArgs { - uint64 span_id = 1; - string resource = 2; -} -message SpanSetResourceReturn {} - -message SpanAddLinkArgs { - uint64 span_id = 1; - SpanLink span_link = 2; -} - -message SpanAddLinkReturn {} - - -message HTTPRequestArgs { - string url = 1; - string method = 2; - DistributedHTTPHeaders headers = 3; - bytes body = 4; -} -message HTTPRequestReturn { - string status_code = 1; -} - -message FlushSpansArgs {} -message FlushSpansReturn {} - -message FlushTraceStatsArgs {} -message FlushTraceStatsReturn {} - - -// OTEL MESSAGES - -message OtelStartSpanArgs { - string name = 1; - optional uint64 parent_id = 3; - optional uint64 span_kind = 9; - optional string service = 4; - optional string resource = 5; - optional string type = 6; - optional int64 timestamp = 7; - repeated SpanLink span_links = 11; - optional DistributedHTTPHeaders http_headers = 10; - Attributes attributes = 8; -} - -message OtelStartSpanReturn { - uint64 span_id = 1; - uint64 trace_id = 2; -} -message OtelEndSpanArgs { - uint64 id = 1; - optional int64 timestamp = 2; -} -message OtelEndSpanReturn {} - -message OtelForceFlushArgs{ - uint32 seconds = 1; -} -message OtelForceFlushReturn{ - bool success = 1; -} - -message OtelFlushSpansArgs { - uint32 seconds = 1; -} -message OtelFlushSpansReturn { - bool success = 1; -} - -message OtelFlushTraceStatsArgs {} -message OtelFlushTraceStatsReturn {} - -message OtelStopTracerArgs {} -message OtelStopTracerReturn {} - -message OtelIsRecordingArgs { - uint64 span_id = 1; -} -message OtelIsRecordingReturn { - bool is_recording = 1; -} - -message OtelSpanContextArgs { - uint64 span_id = 1; -} -message OtelSpanContextReturn { - string span_id = 1; - string trace_id = 2; - string trace_flags = 3; - string trace_state = 4; - bool remote = 5; -} - -message OtelSpanGetCurrentArgs {} -message OtelSpanGetCurrentReturn { - string span_id = 1; - string trace_id = 2; -} - -message OtelSetStatusArgs { - uint64 span_id = 1; - string code = 2; - string description = 3; -} -message OtelSetStatusReturn {} - -message OtelSetNameArgs { - uint64 span_id = 1; - string name = 2; -} -message OtelSetNameReturn {} - -message OtelSetAttributesArgs { - uint64 span_id = 1; - Attributes attributes = 2; -} -message OtelSetAttributesReturn {} - -message OtelAddEventArgs { - uint64 span_id = 1; - string name = 2; - optional int64 timestamp = 3; - Attributes attributes = 4; -} -message OtelAddEventReturn {} - -message OtelRecordExceptionArgs { - uint64 span_id = 1; - string message = 2; - Attributes attributes = 4; -} -message OtelRecordExceptionReturn {} - -message OtelGetAttributeArgs { - uint64 span_id = 1; - string key = 2; -} -message OtelGetAttributeReturn { - ListVal value = 1; -} - -message OtelGetNameArgs { - uint64 span_id = 1; -} -message OtelGetNameReturn { - string name = 1; -} - -message OtelGetLinksArgs { - uint64 span_id = 1; -} -message OtelGetLinksReturn { - repeated SpanLink links = 1; -} - -message Attributes { - map key_vals = 3; -} - -message ListVal { - repeated AttrVal val = 1; -} - -message AttrVal { - oneof val { - bool bool_val = 1; - string string_val = 2; - double double_val = 3; - int64 integer_val = 4; - } -} - -message StopTracerArgs {} -message StopTracerReturn {} diff --git a/utils/parametric/protos/apm_test_client_pb2.py b/utils/parametric/protos/apm_test_client_pb2.py deleted file mode 100644 index 82d46db1328..00000000000 --- a/utils/parametric/protos/apm_test_client_pb2.py +++ /dev/null @@ -1,186 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: protos/apm_test_client.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1cprotos/apm_test_client.proto\"\x14\n\x12GetTraceConfigArgs\"x\n\x14GetTraceConfigReturn\x12\x31\n\x06\x63onfig\x18\x01 \x03(\x0b\x32!.GetTraceConfigReturn.ConfigEntry\x1a-\n\x0b\x43onfigEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xca\x02\n\rStartSpanArgs\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x14\n\x07service\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x16\n\tparent_id\x18\x03 \x01(\x04H\x01\x88\x01\x01\x12\x15\n\x08resource\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x11\n\x04type\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x13\n\x06origin\x18\x06 \x01(\tH\x04\x88\x01\x01\x12\x32\n\x0chttp_headers\x18\x07 \x01(\x0b\x32\x17.DistributedHTTPHeadersH\x05\x88\x01\x01\x12\x1f\n\tspan_tags\x18\x08 \x03(\x0b\x32\x0c.HeaderTuple\x12\x1d\n\nspan_links\x18\t \x03(\x0b\x32\t.SpanLinkB\n\n\x08_serviceB\x0c\n\n_parent_idB\x0b\n\t_resourceB\x07\n\x05_typeB\t\n\x07_originB\x0f\n\r_http_headers\"<\n\x16\x44istributedHTTPHeaders\x12\"\n\x0chttp_headers\x18\x01 \x03(\x0b\x32\x0c.HeaderTuple\"y\n\x08SpanLink\x12\x13\n\tparent_id\x18\x01 \x01(\x04H\x00\x12/\n\x0chttp_headers\x18\x02 \x01(\x0b\x32\x17.DistributedHTTPHeadersH\x00\x12\x1f\n\nattributes\x18\x03 \x01(\x0b\x32\x0b.AttributesB\x06\n\x04\x66rom\")\n\x0bHeaderTuple\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"4\n\x0fStartSpanReturn\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x10\n\x08trace_id\x18\x02 \x01(\x04\"$\n\x11InjectHeadersArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\"Z\n\x13InjectHeadersReturn\x12\x32\n\x0chttp_headers\x18\x01 \x01(\x0b\x32\x17.DistributedHTTPHeadersH\x00\x88\x01\x01\x42\x0f\n\r_http_headers\"\x1c\n\x0e\x46inishSpanArgs\x12\n\n\x02id\x18\x01 \x01(\x04\"\x12\n\x10\x46inishSpanReturn\"\x14\n\x12SpanGetCurrentArgs\"9\n\x14SpanGetCurrentReturn\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x10\n\x08trace_id\x18\x02 \x01(\x04\"\"\n\x0fSpanGetNameArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\"!\n\x11SpanGetNameReturn\x12\x0c\n\x04name\x18\x01 \x01(\t\"&\n\x13SpanGetResourceArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\")\n\x15SpanGetResourceReturn\x12\x10\n\x08resource\x18\x01 \x01(\t\"/\n\x0fSpanGetMetaArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x0b\n\x03key\x18\x02 \x01(\t\",\n\x11SpanGetMetaReturn\x12\x17\n\x05value\x18\x01 \x01(\x0b\x32\x08.AttrVal\"1\n\x11SpanGetMetricArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x0b\n\x03key\x18\x02 \x01(\t\"$\n\x13SpanGetMetricReturn\x12\r\n\x05value\x18\x01 \x01(\x02\">\n\x0fSpanSetMetaArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\t\"\x13\n\x11SpanSetMetaReturn\"@\n\x11SpanSetMetricArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\x02\"\x15\n\x13SpanSetMetricReturn\"\x7f\n\x10SpanSetErrorArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x11\n\x04type\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x07message\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x12\n\x05stack\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\x07\n\x05_typeB\n\n\x08_messageB\x08\n\x06_stack\"\x14\n\x12SpanSetErrorReturn\"8\n\x13SpanSetResourceArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x10\n\x08resource\x18\x02 \x01(\t\"\x17\n\x15SpanSetResourceReturn\"@\n\x0fSpanAddLinkArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x1c\n\tspan_link\x18\x02 \x01(\x0b\x32\t.SpanLink\"\x13\n\x11SpanAddLinkReturn\"f\n\x0fHTTPRequestArgs\x12\x0b\n\x03url\x18\x01 \x01(\t\x12\x0e\n\x06method\x18\x02 \x01(\t\x12(\n\x07headers\x18\x03 \x01(\x0b\x32\x17.DistributedHTTPHeaders\x12\x0c\n\x04\x62ody\x18\x04 \x01(\x0c\"(\n\x11HTTPRequestReturn\x12\x13\n\x0bstatus_code\x18\x01 \x01(\t\"\x10\n\x0e\x46lushSpansArgs\"\x12\n\x10\x46lushSpansReturn\"\x15\n\x13\x46lushTraceStatsArgs\"\x17\n\x15\x46lushTraceStatsReturn\"\xfa\x02\n\x11OtelStartSpanArgs\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x16\n\tparent_id\x18\x03 \x01(\x04H\x00\x88\x01\x01\x12\x16\n\tspan_kind\x18\t \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x07service\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x15\n\x08resource\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x11\n\x04type\x18\x06 \x01(\tH\x04\x88\x01\x01\x12\x16\n\ttimestamp\x18\x07 \x01(\x03H\x05\x88\x01\x01\x12\x1d\n\nspan_links\x18\x0b \x03(\x0b\x32\t.SpanLink\x12\x32\n\x0chttp_headers\x18\n \x01(\x0b\x32\x17.DistributedHTTPHeadersH\x06\x88\x01\x01\x12\x1f\n\nattributes\x18\x08 \x01(\x0b\x32\x0b.AttributesB\x0c\n\n_parent_idB\x0c\n\n_span_kindB\n\n\x08_serviceB\x0b\n\t_resourceB\x07\n\x05_typeB\x0c\n\n_timestampB\x0f\n\r_http_headers\"8\n\x13OtelStartSpanReturn\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x10\n\x08trace_id\x18\x02 \x01(\x04\"C\n\x0fOtelEndSpanArgs\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x16\n\ttimestamp\x18\x02 \x01(\x03H\x00\x88\x01\x01\x42\x0c\n\n_timestamp\"\x13\n\x11OtelEndSpanReturn\"%\n\x12OtelForceFlushArgs\x12\x0f\n\x07seconds\x18\x01 \x01(\r\"\'\n\x14OtelForceFlushReturn\x12\x0f\n\x07success\x18\x01 \x01(\x08\"%\n\x12OtelFlushSpansArgs\x12\x0f\n\x07seconds\x18\x01 \x01(\r\"\'\n\x14OtelFlushSpansReturn\x12\x0f\n\x07success\x18\x01 \x01(\x08\"\x19\n\x17OtelFlushTraceStatsArgs\"\x1b\n\x19OtelFlushTraceStatsReturn\"\x14\n\x12OtelStopTracerArgs\"\x16\n\x14OtelStopTracerReturn\"&\n\x13OtelIsRecordingArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\"-\n\x15OtelIsRecordingReturn\x12\x14\n\x0cis_recording\x18\x01 \x01(\x08\"&\n\x13OtelSpanContextArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\"t\n\x15OtelSpanContextReturn\x12\x0f\n\x07span_id\x18\x01 \x01(\t\x12\x10\n\x08trace_id\x18\x02 \x01(\t\x12\x13\n\x0btrace_flags\x18\x03 \x01(\t\x12\x13\n\x0btrace_state\x18\x04 \x01(\t\x12\x0e\n\x06remote\x18\x05 \x01(\x08\"\x18\n\x16OtelSpanGetCurrentArgs\"=\n\x18OtelSpanGetCurrentReturn\x12\x0f\n\x07span_id\x18\x01 \x01(\t\x12\x10\n\x08trace_id\x18\x02 \x01(\t\"G\n\x11OtelSetStatusArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x0c\n\x04\x63ode\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\"\x15\n\x13OtelSetStatusReturn\"0\n\x0fOtelSetNameArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x13\n\x11OtelSetNameReturn\"I\n\x15OtelSetAttributesArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x1f\n\nattributes\x18\x02 \x01(\x0b\x32\x0b.Attributes\"\x19\n\x17OtelSetAttributesReturn\"x\n\x10OtelAddEventArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x16\n\ttimestamp\x18\x03 \x01(\x03H\x00\x88\x01\x01\x12\x1f\n\nattributes\x18\x04 \x01(\x0b\x32\x0b.AttributesB\x0c\n\n_timestamp\"\x14\n\x12OtelAddEventReturn\"\\\n\x17OtelRecordExceptionArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x1f\n\nattributes\x18\x04 \x01(\x0b\x32\x0b.Attributes\"\x1b\n\x19OtelRecordExceptionReturn\"4\n\x14OtelGetAttributeArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\x12\x0b\n\x03key\x18\x02 \x01(\t\"1\n\x16OtelGetAttributeReturn\x12\x17\n\x05value\x18\x01 \x01(\x0b\x32\x08.ListVal\"\"\n\x0fOtelGetNameArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\"!\n\x11OtelGetNameReturn\x12\x0c\n\x04name\x18\x01 \x01(\t\"#\n\x10OtelGetLinksArgs\x12\x0f\n\x07span_id\x18\x01 \x01(\x04\".\n\x12OtelGetLinksReturn\x12\x18\n\x05links\x18\x01 \x03(\x0b\x32\t.SpanLink\"r\n\nAttributes\x12*\n\x08key_vals\x18\x03 \x03(\x0b\x32\x18.Attributes.KeyValsEntry\x1a\x38\n\x0cKeyValsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x17\n\x05value\x18\x02 \x01(\x0b\x32\x08.ListVal:\x02\x38\x01\" \n\x07ListVal\x12\x15\n\x03val\x18\x01 \x03(\x0b\x32\x08.AttrVal\"g\n\x07\x41ttrVal\x12\x12\n\x08\x62ool_val\x18\x01 \x01(\x08H\x00\x12\x14\n\nstring_val\x18\x02 \x01(\tH\x00\x12\x14\n\ndouble_val\x18\x03 \x01(\x01H\x00\x12\x15\n\x0binteger_val\x18\x04 \x01(\x03H\x00\x42\x05\n\x03val\"\x10\n\x0eStopTracerArgs\"\x12\n\x10StopTracerReturn2\xba\x10\n\tAPMClient\x12/\n\tStartSpan\x12\x0e.StartSpanArgs\x1a\x10.StartSpanReturn\"\x00\x12\x32\n\nFinishSpan\x12\x0f.FinishSpanArgs\x1a\x11.FinishSpanReturn\"\x00\x12>\n\x0eSpanGetCurrent\x12\x13.SpanGetCurrentArgs\x1a\x15.SpanGetCurrentReturn\"\x00\x12\x35\n\x0bSpanGetName\x12\x10.SpanGetNameArgs\x1a\x12.SpanGetNameReturn\"\x00\x12\x41\n\x0fSpanGetResource\x12\x14.SpanGetResourceArgs\x1a\x16.SpanGetResourceReturn\"\x00\x12\x35\n\x0bSpanGetMeta\x12\x10.SpanGetMetaArgs\x1a\x12.SpanGetMetaReturn\"\x00\x12;\n\rSpanGetMetric\x12\x12.SpanGetMetricArgs\x1a\x14.SpanGetMetricReturn\"\x00\x12\x35\n\x0bSpanSetMeta\x12\x10.SpanSetMetaArgs\x1a\x12.SpanSetMetaReturn\"\x00\x12;\n\rSpanSetMetric\x12\x12.SpanSetMetricArgs\x1a\x14.SpanSetMetricReturn\"\x00\x12\x38\n\x0cSpanSetError\x12\x11.SpanSetErrorArgs\x1a\x13.SpanSetErrorReturn\"\x00\x12\x41\n\x0fSpanSetResource\x12\x14.SpanSetResourceArgs\x1a\x16.SpanSetResourceReturn\"\x00\x12\x35\n\x0bSpanAddLink\x12\x10.SpanAddLinkArgs\x1a\x12.SpanAddLinkReturn\"\x00\x12;\n\x11HTTPClientRequest\x12\x10.HTTPRequestArgs\x1a\x12.HTTPRequestReturn\"\x00\x12;\n\x11HTTPServerRequest\x12\x10.HTTPRequestArgs\x1a\x12.HTTPRequestReturn\"\x00\x12;\n\rInjectHeaders\x12\x12.InjectHeadersArgs\x1a\x14.InjectHeadersReturn\"\x00\x12\x32\n\nFlushSpans\x12\x0f.FlushSpansArgs\x1a\x11.FlushSpansReturn\"\x00\x12\x41\n\x0f\x46lushTraceStats\x12\x14.FlushTraceStatsArgs\x1a\x16.FlushTraceStatsReturn\"\x00\x12;\n\rOtelStartSpan\x12\x12.OtelStartSpanArgs\x1a\x14.OtelStartSpanReturn\"\x00\x12\x35\n\x0bOtelEndSpan\x12\x10.OtelEndSpanArgs\x1a\x12.OtelEndSpanReturn\"\x00\x12\x38\n\x0cOtelAddEvent\x12\x11.OtelAddEventArgs\x1a\x13.OtelAddEventReturn\"\x00\x12M\n\x13OtelRecordException\x12\x18.OtelRecordExceptionArgs\x1a\x1a.OtelRecordExceptionReturn\"\x00\x12\x41\n\x0fOtelIsRecording\x12\x14.OtelIsRecordingArgs\x1a\x16.OtelIsRecordingReturn\"\x00\x12\x41\n\x0fOtelSpanContext\x12\x14.OtelSpanContextArgs\x1a\x16.OtelSpanContextReturn\"\x00\x12J\n\x12OtelSpanGetCurrent\x12\x17.OtelSpanGetCurrentArgs\x1a\x19.OtelSpanGetCurrentReturn\"\x00\x12;\n\rOtelSetStatus\x12\x12.OtelSetStatusArgs\x1a\x14.OtelSetStatusReturn\"\x00\x12\x35\n\x0bOtelSetName\x12\x10.OtelSetNameArgs\x1a\x12.OtelSetNameReturn\"\x00\x12G\n\x11OtelSetAttributes\x12\x16.OtelSetAttributesArgs\x1a\x18.OtelSetAttributesReturn\"\x00\x12>\n\x0eOtelFlushSpans\x12\x13.OtelFlushSpansArgs\x1a\x15.OtelFlushSpansReturn\"\x00\x12M\n\x13OtelFlushTraceStats\x12\x18.OtelFlushTraceStatsArgs\x1a\x1a.OtelFlushTraceStatsReturn\"\x00\x12\x44\n\x10OtelGetAttribute\x12\x15.OtelGetAttributeArgs\x1a\x17.OtelGetAttributeReturn\"\x00\x12\x35\n\x0bOtelGetName\x12\x10.OtelGetNameArgs\x1a\x12.OtelGetNameReturn\"\x00\x12\x38\n\x0cOtelGetLinks\x12\x11.OtelGetLinksArgs\x1a\x13.OtelGetLinksReturn\"\x00\x12\x32\n\nStopTracer\x12\x0f.StopTracerArgs\x1a\x11.StopTracerReturn\"\x00\x12>\n\x0eGetTraceConfig\x12\x13.GetTraceConfigArgs\x1a\x15.GetTraceConfigReturn\"\x00\x42&\n\x14\x63om.datadoghq.client\xaa\x02\rApmTestClientb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'protos.apm_test_client_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\024com.datadoghq.client\252\002\rApmTestClient' - _GETTRACECONFIGRETURN_CONFIGENTRY._options = None - _GETTRACECONFIGRETURN_CONFIGENTRY._serialized_options = b'8\001' - _ATTRIBUTES_KEYVALSENTRY._options = None - _ATTRIBUTES_KEYVALSENTRY._serialized_options = b'8\001' - _GETTRACECONFIGARGS._serialized_start=32 - _GETTRACECONFIGARGS._serialized_end=52 - _GETTRACECONFIGRETURN._serialized_start=54 - _GETTRACECONFIGRETURN._serialized_end=174 - _GETTRACECONFIGRETURN_CONFIGENTRY._serialized_start=129 - _GETTRACECONFIGRETURN_CONFIGENTRY._serialized_end=174 - _STARTSPANARGS._serialized_start=177 - _STARTSPANARGS._serialized_end=507 - _DISTRIBUTEDHTTPHEADERS._serialized_start=509 - _DISTRIBUTEDHTTPHEADERS._serialized_end=569 - _SPANLINK._serialized_start=571 - _SPANLINK._serialized_end=692 - _HEADERTUPLE._serialized_start=694 - _HEADERTUPLE._serialized_end=735 - _STARTSPANRETURN._serialized_start=737 - _STARTSPANRETURN._serialized_end=789 - _INJECTHEADERSARGS._serialized_start=791 - _INJECTHEADERSARGS._serialized_end=827 - _INJECTHEADERSRETURN._serialized_start=829 - _INJECTHEADERSRETURN._serialized_end=919 - _FINISHSPANARGS._serialized_start=921 - _FINISHSPANARGS._serialized_end=949 - _FINISHSPANRETURN._serialized_start=951 - _FINISHSPANRETURN._serialized_end=969 - _SPANGETCURRENTARGS._serialized_start=971 - _SPANGETCURRENTARGS._serialized_end=991 - _SPANGETCURRENTRETURN._serialized_start=993 - _SPANGETCURRENTRETURN._serialized_end=1050 - _SPANGETNAMEARGS._serialized_start=1052 - _SPANGETNAMEARGS._serialized_end=1086 - _SPANGETNAMERETURN._serialized_start=1088 - _SPANGETNAMERETURN._serialized_end=1121 - _SPANGETRESOURCEARGS._serialized_start=1123 - _SPANGETRESOURCEARGS._serialized_end=1161 - _SPANGETRESOURCERETURN._serialized_start=1163 - _SPANGETRESOURCERETURN._serialized_end=1204 - _SPANGETMETAARGS._serialized_start=1206 - _SPANGETMETAARGS._serialized_end=1253 - _SPANGETMETARETURN._serialized_start=1255 - _SPANGETMETARETURN._serialized_end=1299 - _SPANGETMETRICARGS._serialized_start=1301 - _SPANGETMETRICARGS._serialized_end=1350 - _SPANGETMETRICRETURN._serialized_start=1352 - _SPANGETMETRICRETURN._serialized_end=1388 - _SPANSETMETAARGS._serialized_start=1390 - _SPANSETMETAARGS._serialized_end=1452 - _SPANSETMETARETURN._serialized_start=1454 - _SPANSETMETARETURN._serialized_end=1473 - _SPANSETMETRICARGS._serialized_start=1475 - _SPANSETMETRICARGS._serialized_end=1539 - _SPANSETMETRICRETURN._serialized_start=1541 - _SPANSETMETRICRETURN._serialized_end=1562 - _SPANSETERRORARGS._serialized_start=1564 - _SPANSETERRORARGS._serialized_end=1691 - _SPANSETERRORRETURN._serialized_start=1693 - _SPANSETERRORRETURN._serialized_end=1713 - _SPANSETRESOURCEARGS._serialized_start=1715 - _SPANSETRESOURCEARGS._serialized_end=1771 - _SPANSETRESOURCERETURN._serialized_start=1773 - _SPANSETRESOURCERETURN._serialized_end=1796 - _SPANADDLINKARGS._serialized_start=1798 - _SPANADDLINKARGS._serialized_end=1862 - _SPANADDLINKRETURN._serialized_start=1864 - _SPANADDLINKRETURN._serialized_end=1883 - _HTTPREQUESTARGS._serialized_start=1885 - _HTTPREQUESTARGS._serialized_end=1987 - _HTTPREQUESTRETURN._serialized_start=1989 - _HTTPREQUESTRETURN._serialized_end=2029 - _FLUSHSPANSARGS._serialized_start=2031 - _FLUSHSPANSARGS._serialized_end=2047 - _FLUSHSPANSRETURN._serialized_start=2049 - _FLUSHSPANSRETURN._serialized_end=2067 - _FLUSHTRACESTATSARGS._serialized_start=2069 - _FLUSHTRACESTATSARGS._serialized_end=2090 - _FLUSHTRACESTATSRETURN._serialized_start=2092 - _FLUSHTRACESTATSRETURN._serialized_end=2115 - _OTELSTARTSPANARGS._serialized_start=2118 - _OTELSTARTSPANARGS._serialized_end=2496 - _OTELSTARTSPANRETURN._serialized_start=2498 - _OTELSTARTSPANRETURN._serialized_end=2554 - _OTELENDSPANARGS._serialized_start=2556 - _OTELENDSPANARGS._serialized_end=2623 - _OTELENDSPANRETURN._serialized_start=2625 - _OTELENDSPANRETURN._serialized_end=2644 - _OTELFORCEFLUSHARGS._serialized_start=2646 - _OTELFORCEFLUSHARGS._serialized_end=2683 - _OTELFORCEFLUSHRETURN._serialized_start=2685 - _OTELFORCEFLUSHRETURN._serialized_end=2724 - _OTELFLUSHSPANSARGS._serialized_start=2726 - _OTELFLUSHSPANSARGS._serialized_end=2763 - _OTELFLUSHSPANSRETURN._serialized_start=2765 - _OTELFLUSHSPANSRETURN._serialized_end=2804 - _OTELFLUSHTRACESTATSARGS._serialized_start=2806 - _OTELFLUSHTRACESTATSARGS._serialized_end=2831 - _OTELFLUSHTRACESTATSRETURN._serialized_start=2833 - _OTELFLUSHTRACESTATSRETURN._serialized_end=2860 - _OTELSTOPTRACERARGS._serialized_start=2862 - _OTELSTOPTRACERARGS._serialized_end=2882 - _OTELSTOPTRACERRETURN._serialized_start=2884 - _OTELSTOPTRACERRETURN._serialized_end=2906 - _OTELISRECORDINGARGS._serialized_start=2908 - _OTELISRECORDINGARGS._serialized_end=2946 - _OTELISRECORDINGRETURN._serialized_start=2948 - _OTELISRECORDINGRETURN._serialized_end=2993 - _OTELSPANCONTEXTARGS._serialized_start=2995 - _OTELSPANCONTEXTARGS._serialized_end=3033 - _OTELSPANCONTEXTRETURN._serialized_start=3035 - _OTELSPANCONTEXTRETURN._serialized_end=3151 - _OTELSPANGETCURRENTARGS._serialized_start=3153 - _OTELSPANGETCURRENTARGS._serialized_end=3177 - _OTELSPANGETCURRENTRETURN._serialized_start=3179 - _OTELSPANGETCURRENTRETURN._serialized_end=3240 - _OTELSETSTATUSARGS._serialized_start=3242 - _OTELSETSTATUSARGS._serialized_end=3313 - _OTELSETSTATUSRETURN._serialized_start=3315 - _OTELSETSTATUSRETURN._serialized_end=3336 - _OTELSETNAMEARGS._serialized_start=3338 - _OTELSETNAMEARGS._serialized_end=3386 - _OTELSETNAMERETURN._serialized_start=3388 - _OTELSETNAMERETURN._serialized_end=3407 - _OTELSETATTRIBUTESARGS._serialized_start=3409 - _OTELSETATTRIBUTESARGS._serialized_end=3482 - _OTELSETATTRIBUTESRETURN._serialized_start=3484 - _OTELSETATTRIBUTESRETURN._serialized_end=3509 - _OTELADDEVENTARGS._serialized_start=3511 - _OTELADDEVENTARGS._serialized_end=3631 - _OTELADDEVENTRETURN._serialized_start=3633 - _OTELADDEVENTRETURN._serialized_end=3653 - _OTELRECORDEXCEPTIONARGS._serialized_start=3655 - _OTELRECORDEXCEPTIONARGS._serialized_end=3747 - _OTELRECORDEXCEPTIONRETURN._serialized_start=3749 - _OTELRECORDEXCEPTIONRETURN._serialized_end=3776 - _OTELGETATTRIBUTEARGS._serialized_start=3778 - _OTELGETATTRIBUTEARGS._serialized_end=3830 - _OTELGETATTRIBUTERETURN._serialized_start=3832 - _OTELGETATTRIBUTERETURN._serialized_end=3881 - _OTELGETNAMEARGS._serialized_start=3883 - _OTELGETNAMEARGS._serialized_end=3917 - _OTELGETNAMERETURN._serialized_start=3919 - _OTELGETNAMERETURN._serialized_end=3952 - _OTELGETLINKSARGS._serialized_start=3954 - _OTELGETLINKSARGS._serialized_end=3989 - _OTELGETLINKSRETURN._serialized_start=3991 - _OTELGETLINKSRETURN._serialized_end=4037 - _ATTRIBUTES._serialized_start=4039 - _ATTRIBUTES._serialized_end=4153 - _ATTRIBUTES_KEYVALSENTRY._serialized_start=4097 - _ATTRIBUTES_KEYVALSENTRY._serialized_end=4153 - _LISTVAL._serialized_start=4155 - _LISTVAL._serialized_end=4187 - _ATTRVAL._serialized_start=4189 - _ATTRVAL._serialized_end=4292 - _STOPTRACERARGS._serialized_start=4294 - _STOPTRACERARGS._serialized_end=4310 - _STOPTRACERRETURN._serialized_start=4312 - _STOPTRACERRETURN._serialized_end=4330 - _APMCLIENT._serialized_start=4333 - _APMCLIENT._serialized_end=6439 -# @@protoc_insertion_point(module_scope) diff --git a/utils/parametric/protos/apm_test_client_pb2_grpc.py b/utils/parametric/protos/apm_test_client_pb2_grpc.py deleted file mode 100644 index bda1012bfc7..00000000000 --- a/utils/parametric/protos/apm_test_client_pb2_grpc.py +++ /dev/null @@ -1,1158 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from utils.parametric.protos import apm_test_client_pb2 as protos_dot_apm__test__client__pb2 - - -class APMClientStub(object): - """Interface of APM clients to be used for shared testing. - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.StartSpan = channel.unary_unary( - '/APMClient/StartSpan', - request_serializer=protos_dot_apm__test__client__pb2.StartSpanArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.StartSpanReturn.FromString, - ) - self.FinishSpan = channel.unary_unary( - '/APMClient/FinishSpan', - request_serializer=protos_dot_apm__test__client__pb2.FinishSpanArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.FinishSpanReturn.FromString, - ) - self.SpanGetCurrent = channel.unary_unary( - '/APMClient/SpanGetCurrent', - request_serializer=protos_dot_apm__test__client__pb2.SpanGetCurrentArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.SpanGetCurrentReturn.FromString, - ) - self.SpanGetName = channel.unary_unary( - '/APMClient/SpanGetName', - request_serializer=protos_dot_apm__test__client__pb2.SpanGetNameArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.SpanGetNameReturn.FromString, - ) - self.SpanGetResource = channel.unary_unary( - '/APMClient/SpanGetResource', - request_serializer=protos_dot_apm__test__client__pb2.SpanGetResourceArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.SpanGetResourceReturn.FromString, - ) - self.SpanGetMeta = channel.unary_unary( - '/APMClient/SpanGetMeta', - request_serializer=protos_dot_apm__test__client__pb2.SpanGetMetaArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.SpanGetMetaReturn.FromString, - ) - self.SpanGetMetric = channel.unary_unary( - '/APMClient/SpanGetMetric', - request_serializer=protos_dot_apm__test__client__pb2.SpanGetMetricArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.SpanGetMetricReturn.FromString, - ) - self.SpanSetMeta = channel.unary_unary( - '/APMClient/SpanSetMeta', - request_serializer=protos_dot_apm__test__client__pb2.SpanSetMetaArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.SpanSetMetaReturn.FromString, - ) - self.SpanSetMetric = channel.unary_unary( - '/APMClient/SpanSetMetric', - request_serializer=protos_dot_apm__test__client__pb2.SpanSetMetricArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.SpanSetMetricReturn.FromString, - ) - self.SpanSetError = channel.unary_unary( - '/APMClient/SpanSetError', - request_serializer=protos_dot_apm__test__client__pb2.SpanSetErrorArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.SpanSetErrorReturn.FromString, - ) - self.SpanSetResource = channel.unary_unary( - '/APMClient/SpanSetResource', - request_serializer=protos_dot_apm__test__client__pb2.SpanSetResourceArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.SpanSetResourceReturn.FromString, - ) - self.SpanAddLink = channel.unary_unary( - '/APMClient/SpanAddLink', - request_serializer=protos_dot_apm__test__client__pb2.SpanAddLinkArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.SpanAddLinkReturn.FromString, - ) - self.HTTPClientRequest = channel.unary_unary( - '/APMClient/HTTPClientRequest', - request_serializer=protos_dot_apm__test__client__pb2.HTTPRequestArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.HTTPRequestReturn.FromString, - ) - self.HTTPServerRequest = channel.unary_unary( - '/APMClient/HTTPServerRequest', - request_serializer=protos_dot_apm__test__client__pb2.HTTPRequestArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.HTTPRequestReturn.FromString, - ) - self.InjectHeaders = channel.unary_unary( - '/APMClient/InjectHeaders', - request_serializer=protos_dot_apm__test__client__pb2.InjectHeadersArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.InjectHeadersReturn.FromString, - ) - self.FlushSpans = channel.unary_unary( - '/APMClient/FlushSpans', - request_serializer=protos_dot_apm__test__client__pb2.FlushSpansArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.FlushSpansReturn.FromString, - ) - self.FlushTraceStats = channel.unary_unary( - '/APMClient/FlushTraceStats', - request_serializer=protos_dot_apm__test__client__pb2.FlushTraceStatsArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.FlushTraceStatsReturn.FromString, - ) - self.OtelStartSpan = channel.unary_unary( - '/APMClient/OtelStartSpan', - request_serializer=protos_dot_apm__test__client__pb2.OtelStartSpanArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelStartSpanReturn.FromString, - ) - self.OtelEndSpan = channel.unary_unary( - '/APMClient/OtelEndSpan', - request_serializer=protos_dot_apm__test__client__pb2.OtelEndSpanArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelEndSpanReturn.FromString, - ) - self.OtelAddEvent = channel.unary_unary( - '/APMClient/OtelAddEvent', - request_serializer=protos_dot_apm__test__client__pb2.OtelAddEventArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelAddEventReturn.FromString, - ) - self.OtelRecordException = channel.unary_unary( - '/APMClient/OtelRecordException', - request_serializer=protos_dot_apm__test__client__pb2.OtelRecordExceptionArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelRecordExceptionReturn.FromString, - ) - self.OtelIsRecording = channel.unary_unary( - '/APMClient/OtelIsRecording', - request_serializer=protos_dot_apm__test__client__pb2.OtelIsRecordingArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelIsRecordingReturn.FromString, - ) - self.OtelSpanContext = channel.unary_unary( - '/APMClient/OtelSpanContext', - request_serializer=protos_dot_apm__test__client__pb2.OtelSpanContextArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelSpanContextReturn.FromString, - ) - self.OtelSpanGetCurrent = channel.unary_unary( - '/APMClient/OtelSpanGetCurrent', - request_serializer=protos_dot_apm__test__client__pb2.OtelSpanGetCurrentArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelSpanGetCurrentReturn.FromString, - ) - self.OtelSetStatus = channel.unary_unary( - '/APMClient/OtelSetStatus', - request_serializer=protos_dot_apm__test__client__pb2.OtelSetStatusArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelSetStatusReturn.FromString, - ) - self.OtelSetName = channel.unary_unary( - '/APMClient/OtelSetName', - request_serializer=protos_dot_apm__test__client__pb2.OtelSetNameArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelSetNameReturn.FromString, - ) - self.OtelSetAttributes = channel.unary_unary( - '/APMClient/OtelSetAttributes', - request_serializer=protos_dot_apm__test__client__pb2.OtelSetAttributesArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelSetAttributesReturn.FromString, - ) - self.OtelFlushSpans = channel.unary_unary( - '/APMClient/OtelFlushSpans', - request_serializer=protos_dot_apm__test__client__pb2.OtelFlushSpansArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelFlushSpansReturn.FromString, - ) - self.OtelFlushTraceStats = channel.unary_unary( - '/APMClient/OtelFlushTraceStats', - request_serializer=protos_dot_apm__test__client__pb2.OtelFlushTraceStatsArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelFlushTraceStatsReturn.FromString, - ) - self.OtelGetAttribute = channel.unary_unary( - '/APMClient/OtelGetAttribute', - request_serializer=protos_dot_apm__test__client__pb2.OtelGetAttributeArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelGetAttributeReturn.FromString, - ) - self.OtelGetName = channel.unary_unary( - '/APMClient/OtelGetName', - request_serializer=protos_dot_apm__test__client__pb2.OtelGetNameArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelGetNameReturn.FromString, - ) - self.OtelGetLinks = channel.unary_unary( - '/APMClient/OtelGetLinks', - request_serializer=protos_dot_apm__test__client__pb2.OtelGetLinksArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.OtelGetLinksReturn.FromString, - ) - self.StopTracer = channel.unary_unary( - '/APMClient/StopTracer', - request_serializer=protos_dot_apm__test__client__pb2.StopTracerArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.StopTracerReturn.FromString, - ) - self.GetTraceConfig = channel.unary_unary( - '/APMClient/GetTraceConfig', - request_serializer=protos_dot_apm__test__client__pb2.GetTraceConfigArgs.SerializeToString, - response_deserializer=protos_dot_apm__test__client__pb2.GetTraceConfigReturn.FromString, - ) - - -class APMClientServicer(object): - """Interface of APM clients to be used for shared testing. - """ - - def StartSpan(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def FinishSpan(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SpanGetCurrent(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SpanGetName(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SpanGetResource(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SpanGetMeta(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SpanGetMetric(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SpanSetMeta(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SpanSetMetric(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SpanSetError(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SpanSetResource(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SpanAddLink(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def HTTPClientRequest(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def HTTPServerRequest(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def InjectHeaders(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def FlushSpans(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def FlushTraceStats(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelStartSpan(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelEndSpan(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelAddEvent(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelRecordException(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelIsRecording(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelSpanContext(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelSpanGetCurrent(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelSetStatus(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelSetName(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelSetAttributes(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelFlushSpans(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelFlushTraceStats(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelGetAttribute(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelGetName(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def OtelGetLinks(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def StopTracer(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetTraceConfig(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_APMClientServicer_to_server(servicer, server): - rpc_method_handlers = { - 'StartSpan': grpc.unary_unary_rpc_method_handler( - servicer.StartSpan, - request_deserializer=protos_dot_apm__test__client__pb2.StartSpanArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.StartSpanReturn.SerializeToString, - ), - 'FinishSpan': grpc.unary_unary_rpc_method_handler( - servicer.FinishSpan, - request_deserializer=protos_dot_apm__test__client__pb2.FinishSpanArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.FinishSpanReturn.SerializeToString, - ), - 'SpanGetCurrent': grpc.unary_unary_rpc_method_handler( - servicer.SpanGetCurrent, - request_deserializer=protos_dot_apm__test__client__pb2.SpanGetCurrentArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.SpanGetCurrentReturn.SerializeToString, - ), - 'SpanGetName': grpc.unary_unary_rpc_method_handler( - servicer.SpanGetName, - request_deserializer=protos_dot_apm__test__client__pb2.SpanGetNameArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.SpanGetNameReturn.SerializeToString, - ), - 'SpanGetResource': grpc.unary_unary_rpc_method_handler( - servicer.SpanGetResource, - request_deserializer=protos_dot_apm__test__client__pb2.SpanGetResourceArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.SpanGetResourceReturn.SerializeToString, - ), - 'SpanGetMeta': grpc.unary_unary_rpc_method_handler( - servicer.SpanGetMeta, - request_deserializer=protos_dot_apm__test__client__pb2.SpanGetMetaArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.SpanGetMetaReturn.SerializeToString, - ), - 'SpanGetMetric': grpc.unary_unary_rpc_method_handler( - servicer.SpanGetMetric, - request_deserializer=protos_dot_apm__test__client__pb2.SpanGetMetricArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.SpanGetMetricReturn.SerializeToString, - ), - 'SpanSetMeta': grpc.unary_unary_rpc_method_handler( - servicer.SpanSetMeta, - request_deserializer=protos_dot_apm__test__client__pb2.SpanSetMetaArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.SpanSetMetaReturn.SerializeToString, - ), - 'SpanSetMetric': grpc.unary_unary_rpc_method_handler( - servicer.SpanSetMetric, - request_deserializer=protos_dot_apm__test__client__pb2.SpanSetMetricArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.SpanSetMetricReturn.SerializeToString, - ), - 'SpanSetError': grpc.unary_unary_rpc_method_handler( - servicer.SpanSetError, - request_deserializer=protos_dot_apm__test__client__pb2.SpanSetErrorArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.SpanSetErrorReturn.SerializeToString, - ), - 'SpanSetResource': grpc.unary_unary_rpc_method_handler( - servicer.SpanSetResource, - request_deserializer=protos_dot_apm__test__client__pb2.SpanSetResourceArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.SpanSetResourceReturn.SerializeToString, - ), - 'SpanAddLink': grpc.unary_unary_rpc_method_handler( - servicer.SpanAddLink, - request_deserializer=protos_dot_apm__test__client__pb2.SpanAddLinkArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.SpanAddLinkReturn.SerializeToString, - ), - 'HTTPClientRequest': grpc.unary_unary_rpc_method_handler( - servicer.HTTPClientRequest, - request_deserializer=protos_dot_apm__test__client__pb2.HTTPRequestArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.HTTPRequestReturn.SerializeToString, - ), - 'HTTPServerRequest': grpc.unary_unary_rpc_method_handler( - servicer.HTTPServerRequest, - request_deserializer=protos_dot_apm__test__client__pb2.HTTPRequestArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.HTTPRequestReturn.SerializeToString, - ), - 'InjectHeaders': grpc.unary_unary_rpc_method_handler( - servicer.InjectHeaders, - request_deserializer=protos_dot_apm__test__client__pb2.InjectHeadersArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.InjectHeadersReturn.SerializeToString, - ), - 'FlushSpans': grpc.unary_unary_rpc_method_handler( - servicer.FlushSpans, - request_deserializer=protos_dot_apm__test__client__pb2.FlushSpansArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.FlushSpansReturn.SerializeToString, - ), - 'FlushTraceStats': grpc.unary_unary_rpc_method_handler( - servicer.FlushTraceStats, - request_deserializer=protos_dot_apm__test__client__pb2.FlushTraceStatsArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.FlushTraceStatsReturn.SerializeToString, - ), - 'OtelStartSpan': grpc.unary_unary_rpc_method_handler( - servicer.OtelStartSpan, - request_deserializer=protos_dot_apm__test__client__pb2.OtelStartSpanArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelStartSpanReturn.SerializeToString, - ), - 'OtelEndSpan': grpc.unary_unary_rpc_method_handler( - servicer.OtelEndSpan, - request_deserializer=protos_dot_apm__test__client__pb2.OtelEndSpanArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelEndSpanReturn.SerializeToString, - ), - 'OtelAddEvent': grpc.unary_unary_rpc_method_handler( - servicer.OtelAddEvent, - request_deserializer=protos_dot_apm__test__client__pb2.OtelAddEventArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelAddEventReturn.SerializeToString, - ), - 'OtelRecordException': grpc.unary_unary_rpc_method_handler( - servicer.OtelRecordException, - request_deserializer=protos_dot_apm__test__client__pb2.OtelRecordExceptionArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelRecordExceptionReturn.SerializeToString, - ), - 'OtelIsRecording': grpc.unary_unary_rpc_method_handler( - servicer.OtelIsRecording, - request_deserializer=protos_dot_apm__test__client__pb2.OtelIsRecordingArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelIsRecordingReturn.SerializeToString, - ), - 'OtelSpanContext': grpc.unary_unary_rpc_method_handler( - servicer.OtelSpanContext, - request_deserializer=protos_dot_apm__test__client__pb2.OtelSpanContextArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelSpanContextReturn.SerializeToString, - ), - 'OtelSpanGetCurrent': grpc.unary_unary_rpc_method_handler( - servicer.OtelSpanGetCurrent, - request_deserializer=protos_dot_apm__test__client__pb2.OtelSpanGetCurrentArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelSpanGetCurrentReturn.SerializeToString, - ), - 'OtelSetStatus': grpc.unary_unary_rpc_method_handler( - servicer.OtelSetStatus, - request_deserializer=protos_dot_apm__test__client__pb2.OtelSetStatusArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelSetStatusReturn.SerializeToString, - ), - 'OtelSetName': grpc.unary_unary_rpc_method_handler( - servicer.OtelSetName, - request_deserializer=protos_dot_apm__test__client__pb2.OtelSetNameArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelSetNameReturn.SerializeToString, - ), - 'OtelSetAttributes': grpc.unary_unary_rpc_method_handler( - servicer.OtelSetAttributes, - request_deserializer=protos_dot_apm__test__client__pb2.OtelSetAttributesArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelSetAttributesReturn.SerializeToString, - ), - 'OtelFlushSpans': grpc.unary_unary_rpc_method_handler( - servicer.OtelFlushSpans, - request_deserializer=protos_dot_apm__test__client__pb2.OtelFlushSpansArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelFlushSpansReturn.SerializeToString, - ), - 'OtelFlushTraceStats': grpc.unary_unary_rpc_method_handler( - servicer.OtelFlushTraceStats, - request_deserializer=protos_dot_apm__test__client__pb2.OtelFlushTraceStatsArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelFlushTraceStatsReturn.SerializeToString, - ), - 'OtelGetAttribute': grpc.unary_unary_rpc_method_handler( - servicer.OtelGetAttribute, - request_deserializer=protos_dot_apm__test__client__pb2.OtelGetAttributeArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelGetAttributeReturn.SerializeToString, - ), - 'OtelGetName': grpc.unary_unary_rpc_method_handler( - servicer.OtelGetName, - request_deserializer=protos_dot_apm__test__client__pb2.OtelGetNameArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelGetNameReturn.SerializeToString, - ), - 'OtelGetLinks': grpc.unary_unary_rpc_method_handler( - servicer.OtelGetLinks, - request_deserializer=protos_dot_apm__test__client__pb2.OtelGetLinksArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.OtelGetLinksReturn.SerializeToString, - ), - 'StopTracer': grpc.unary_unary_rpc_method_handler( - servicer.StopTracer, - request_deserializer=protos_dot_apm__test__client__pb2.StopTracerArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.StopTracerReturn.SerializeToString, - ), - 'GetTraceConfig': grpc.unary_unary_rpc_method_handler( - servicer.GetTraceConfig, - request_deserializer=protos_dot_apm__test__client__pb2.GetTraceConfigArgs.FromString, - response_serializer=protos_dot_apm__test__client__pb2.GetTraceConfigReturn.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'APMClient', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class APMClient(object): - """Interface of APM clients to be used for shared testing. - """ - - @staticmethod - def StartSpan(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/StartSpan', - protos_dot_apm__test__client__pb2.StartSpanArgs.SerializeToString, - protos_dot_apm__test__client__pb2.StartSpanReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def FinishSpan(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/FinishSpan', - protos_dot_apm__test__client__pb2.FinishSpanArgs.SerializeToString, - protos_dot_apm__test__client__pb2.FinishSpanReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def SpanGetCurrent(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/SpanGetCurrent', - protos_dot_apm__test__client__pb2.SpanGetCurrentArgs.SerializeToString, - protos_dot_apm__test__client__pb2.SpanGetCurrentReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def SpanGetName(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/SpanGetName', - protos_dot_apm__test__client__pb2.SpanGetNameArgs.SerializeToString, - protos_dot_apm__test__client__pb2.SpanGetNameReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def SpanGetResource(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/SpanGetResource', - protos_dot_apm__test__client__pb2.SpanGetResourceArgs.SerializeToString, - protos_dot_apm__test__client__pb2.SpanGetResourceReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def SpanGetMeta(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/SpanGetMeta', - protos_dot_apm__test__client__pb2.SpanGetMetaArgs.SerializeToString, - protos_dot_apm__test__client__pb2.SpanGetMetaReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def SpanGetMetric(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/SpanGetMetric', - protos_dot_apm__test__client__pb2.SpanGetMetricArgs.SerializeToString, - protos_dot_apm__test__client__pb2.SpanGetMetricReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def SpanSetMeta(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/SpanSetMeta', - protos_dot_apm__test__client__pb2.SpanSetMetaArgs.SerializeToString, - protos_dot_apm__test__client__pb2.SpanSetMetaReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def SpanSetMetric(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/SpanSetMetric', - protos_dot_apm__test__client__pb2.SpanSetMetricArgs.SerializeToString, - protos_dot_apm__test__client__pb2.SpanSetMetricReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def SpanSetError(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/SpanSetError', - protos_dot_apm__test__client__pb2.SpanSetErrorArgs.SerializeToString, - protos_dot_apm__test__client__pb2.SpanSetErrorReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def SpanSetResource(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/SpanSetResource', - protos_dot_apm__test__client__pb2.SpanSetResourceArgs.SerializeToString, - protos_dot_apm__test__client__pb2.SpanSetResourceReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def SpanAddLink(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/SpanAddLink', - protos_dot_apm__test__client__pb2.SpanAddLinkArgs.SerializeToString, - protos_dot_apm__test__client__pb2.SpanAddLinkReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def HTTPClientRequest(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/HTTPClientRequest', - protos_dot_apm__test__client__pb2.HTTPRequestArgs.SerializeToString, - protos_dot_apm__test__client__pb2.HTTPRequestReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def HTTPServerRequest(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/HTTPServerRequest', - protos_dot_apm__test__client__pb2.HTTPRequestArgs.SerializeToString, - protos_dot_apm__test__client__pb2.HTTPRequestReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def InjectHeaders(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/InjectHeaders', - protos_dot_apm__test__client__pb2.InjectHeadersArgs.SerializeToString, - protos_dot_apm__test__client__pb2.InjectHeadersReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def FlushSpans(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/FlushSpans', - protos_dot_apm__test__client__pb2.FlushSpansArgs.SerializeToString, - protos_dot_apm__test__client__pb2.FlushSpansReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def FlushTraceStats(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/FlushTraceStats', - protos_dot_apm__test__client__pb2.FlushTraceStatsArgs.SerializeToString, - protos_dot_apm__test__client__pb2.FlushTraceStatsReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelStartSpan(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelStartSpan', - protos_dot_apm__test__client__pb2.OtelStartSpanArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelStartSpanReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelEndSpan(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelEndSpan', - protos_dot_apm__test__client__pb2.OtelEndSpanArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelEndSpanReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelAddEvent(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelAddEvent', - protos_dot_apm__test__client__pb2.OtelAddEventArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelAddEventReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelRecordException(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelRecordException', - protos_dot_apm__test__client__pb2.OtelRecordExceptionArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelRecordExceptionReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelIsRecording(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelIsRecording', - protos_dot_apm__test__client__pb2.OtelIsRecordingArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelIsRecordingReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelSpanContext(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelSpanContext', - protos_dot_apm__test__client__pb2.OtelSpanContextArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelSpanContextReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelSpanGetCurrent(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelSpanGetCurrent', - protos_dot_apm__test__client__pb2.OtelSpanGetCurrentArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelSpanGetCurrentReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelSetStatus(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelSetStatus', - protos_dot_apm__test__client__pb2.OtelSetStatusArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelSetStatusReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelSetName(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelSetName', - protos_dot_apm__test__client__pb2.OtelSetNameArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelSetNameReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelSetAttributes(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelSetAttributes', - protos_dot_apm__test__client__pb2.OtelSetAttributesArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelSetAttributesReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelFlushSpans(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelFlushSpans', - protos_dot_apm__test__client__pb2.OtelFlushSpansArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelFlushSpansReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelFlushTraceStats(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelFlushTraceStats', - protos_dot_apm__test__client__pb2.OtelFlushTraceStatsArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelFlushTraceStatsReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelGetAttribute(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelGetAttribute', - protos_dot_apm__test__client__pb2.OtelGetAttributeArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelGetAttributeReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelGetName(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelGetName', - protos_dot_apm__test__client__pb2.OtelGetNameArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelGetNameReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def OtelGetLinks(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/OtelGetLinks', - protos_dot_apm__test__client__pb2.OtelGetLinksArgs.SerializeToString, - protos_dot_apm__test__client__pb2.OtelGetLinksReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def StopTracer(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/StopTracer', - protos_dot_apm__test__client__pb2.StopTracerArgs.SerializeToString, - protos_dot_apm__test__client__pb2.StopTracerReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetTraceConfig(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/APMClient/GetTraceConfig', - protos_dot_apm__test__client__pb2.GetTraceConfigArgs.SerializeToString, - protos_dot_apm__test__client__pb2.GetTraceConfigReturn.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/utils/parametric/spec/otel_trace.py b/utils/parametric/spec/otel_trace.py index fa538db6b13..5edbe8f42f8 100644 --- a/utils/parametric/spec/otel_trace.py +++ b/utils/parametric/spec/otel_trace.py @@ -1,21 +1,4 @@ -from typing import List from typing import TypedDict -from utils.parametric.protos import apm_test_client_pb2 as pb - -OTEL_UNSET_CODE = "UNSET" -OTEL_ERROR_CODE = "ERROR" -OTEL_OK_CODE = "OK" - -SK_UNSPECIFIED = 0 -SK_INTERNAL = 1 -SK_SERVER = 2 -SK_CLIENT = 3 -SK_PRODUCER = 4 -SK_CONSUMER = 5 - - -class OtelSpan(TypedDict): - resource: str class OtelSpanContext(TypedDict): @@ -24,53 +7,3 @@ class OtelSpanContext(TypedDict): trace_flags: str trace_state: str remote: bool - - -OtelTrace = List[OtelSpan] - - -def otel_span(name: str) -> OtelSpan: - return {"resource": name} - - -def check_list_type(value, t: type) -> bool: - if value and all(isinstance(item, t) for item in value): - return True - return False - - -# values for otel span attributes can be a list - -# to avoid having multiple map fields in Attributes -# (one where the value is type ListVal, another where value is type AttrVal) -# we just represent all values in List form -def get_val(v) -> pb.ListVal: - if isinstance(v, list) and check_list_type(v, str): - return pb.ListVal(val=[pb.AttrVal(string_val=i) for i in v]) - if isinstance(v, list) and check_list_type(v, bool): - return pb.ListVal(val=[pb.AttrVal(bool_val=i) for i in v]) - if isinstance(v, list) and check_list_type(v, float): - return pb.ListVal(val=[pb.AttrVal(double_val=i) for i in v]) - if isinstance(v, list) and check_list_type(v, int): - return pb.ListVal(val=[pb.AttrVal(integer_val=i) for i in v]) - if isinstance(v, str): - return pb.ListVal(val=[pb.AttrVal(string_val=v)]) - if isinstance(v, bool): - return pb.ListVal(val=[pb.AttrVal(bool_val=v)]) - if isinstance(v, float): - return pb.ListVal(val=[pb.AttrVal(double_val=v)]) - if isinstance(v, int): - return pb.ListVal(val=[pb.AttrVal(integer_val=v)]) - return None - - -# converts a dictionary containing span attributes into -# the proto message "Attributes" -def convert_to_proto(attributes: dict) -> pb.Attributes: - list_attr = {} - if not attributes: - return pb.Attributes() - for k, v in attributes.items(): - ret = get_val(v) - if ret: - list_attr[k] = ret - return pb.Attributes(key_vals=list_attr) diff --git a/utils/parametric/spec/remoteconfig.py b/utils/parametric/spec/remoteconfig.py index 755ffa86b40..78cfb6c670e 100644 --- a/utils/parametric/spec/remoteconfig.py +++ b/utils/parametric/spec/remoteconfig.py @@ -1,6 +1,5 @@ -import enum -from typing import Literal -from typing import Tuple +from typing import Any, Literal +from utils.dd_constants import Capabilities # Remote Configuration apply status is used by clients to report the application status of a Remote Configuration @@ -13,25 +12,5 @@ APPLY_STATUS = Literal[0, 1, 2, 3] -class Capabilities(enum.IntEnum): - ASM_ACTIVATION = 1 - ASM_IP_BLOCKING = 2 - ASM_DD_RULES = 3 - ASM_EXCLUSIONS = 4 - ASM_REQUEST_BLOCKING = 5 - ASM_ASM_RESPONSE_BLOCKING = 6 - ASM_USER_BLOCKING = 7 - ASM_CUSTOM_RULES = 8 - ASM_CUSTOM_BLOCKING_RESPONSE = 9 - ASM_TRUSTED_IPS = 10 - ASM_API_SECURITY_SAMPLE_RATE = 11 - APM_TRACING_SAMPLE_RATE = 12 - APM_TRACING_LOGS_INJECTION = 13 - APM_TRACING_HTTP_HEADER_TAGS = 14 - APM_TRACING_CUSTOM_TAGS = 15 - APM_TRACING_ENABLED = 19 - APM_TRACING_SAMPLE_RULES = 29 - - -def human_readable_capabilities(caps: int) -> Tuple[str]: +def human_readable_capabilities(caps: int) -> tuple[Any, ...]: return tuple(c.name for c in Capabilities if caps >> c & 1) diff --git a/utils/parametric/spec/trace.py b/utils/parametric/spec/trace.py index 3f90fb8b859..010215d2d02 100644 --- a/utils/parametric/spec/trace.py +++ b/utils/parametric/spec/trace.py @@ -1,19 +1,13 @@ -""" -Tracing constants, data structures and helper methods. +"""Tracing constants, data structures and helper methods. These are used to specify, test and work with trace data and protocols. """ + import json -import math -from typing import Dict -from typing import List -from typing import Optional from typing import TypedDict -from typing import Union from ddapm_test_agent.trace import Span from ddapm_test_agent.trace import Trace -from ddapm_test_agent.trace import root_span import msgpack from ddsketch.ddsketch import BaseDDSketch @@ -65,6 +59,7 @@ SAMPLING_RULE_PRIORITY_RATE = "_dd.rule_psr" SAMPLING_LIMIT_PRIORITY_RATE = "_dd.limit_psr" + # Note that class attributes are golang style to match the payload. class V06StatsAggr(TypedDict): """Stats aggregation data structure used in the v0.6/stats protocol.""" @@ -86,14 +81,14 @@ class V06StatsAggr(TypedDict): class V06StatsBucket(TypedDict): Start: int Duration: int - Stats: List[V06StatsAggr] + Stats: list[V06StatsAggr] class V06StatsPayload(TypedDict): - Hostname: Optional[str] - Env: Optional[str] - Version: Optional[str] - Stats: List[V06StatsBucket] + Hostname: str | None + Env: str | None + Version: str | None + Stats: list[V06StatsBucket] def _v06_store_from_proto(proto: StorePb) -> CollapsingLowestDenseStore: @@ -115,14 +110,14 @@ def _v06_sketch_from_proto(proto: DDSketchPb) -> BaseDDSketch: mapping = KeyMappingProto.from_proto(proto.mapping) store = _v06_store_from_proto(proto.positiveValues) negative_store = _v06_store_from_proto(proto.negativeValues) - return BaseDDSketch(mapping=mapping, store=store, negative_store=negative_store, zero_count=proto.zeroCount,) + return BaseDDSketch(mapping=mapping, store=store, negative_store=negative_store, zero_count=proto.zeroCount) def decode_v06_stats(data: bytes) -> V06StatsPayload: payload = msgpack.unpackb(data) - stats_buckets: List[V06StatsBucket] = [] + stats_buckets: list[V06StatsBucket] = [] for raw_bucket in payload["Stats"]: - stats: List[V06StatsAggr] = [] + stats: list[V06StatsAggr] = [] for raw_stats in raw_bucket["Stats"]: ok_summary = DDSketchPb() ok_summary.ParseFromString(raw_stats["OkSummary"]) @@ -146,115 +141,63 @@ def decode_v06_stats(data: bytes) -> V06StatsPayload: if ok_summary.mapping.gamma > 1: stats.append(stat) - bucket = V06StatsBucket(Start=raw_bucket["Start"], Duration=raw_bucket["Duration"], Stats=stats,) + bucket = V06StatsBucket(Start=raw_bucket["Start"], Duration=raw_bucket["Duration"], Stats=stats) stats_buckets.append(bucket) return V06StatsPayload( - Hostname=payload.get("Hostname"), Env=payload.get("Env"), Version=payload.get("Version"), Stats=stats_buckets, + Hostname=payload.get("Hostname"), Env=payload.get("Env"), Version=payload.get("Version"), Stats=stats_buckets ) -def _span_similarity(s1: Span, s2: Span) -> int: - """Return a similarity rating for the two given spans.""" - score = 0 - - for key in set(s1.keys() & s2.keys()): - if s1[key] == s2[key]: - score += 1 - - s1_meta = s1.get("meta", {}) - s2_meta = s2.get("meta", {}) - for key in set(s1_meta.keys()) & set(s2_meta.keys()): - if s1_meta[key] == s2_meta[key]: - score += 1 - - s1_metrics = s1.get("metrics", {}) - s2_metrics = s2.get("metrics", {}) - for key in set(s1_metrics.keys()) & set(s2_metrics.keys()): - if s1_metrics[key] == s2_metrics[key]: - score += 1 - return score - - -def find_similar_trace_by_root(traces: List[Trace], span: Span) -> Trace: - """Return the trace from `traces` with root span most similar to `span`.""" - assert len(traces) > 0 - - max_similarity = -math.inf - max_score_trace = traces[0] +def find_trace(traces: list[Trace], trace_id: int) -> Trace: + """Return the trace from `traces` that match a `trace_id`.""" + # TODO: Ensure all parametric applications return uint64 trace ids (not strings or bigints) + trace_id = ((1 << 64) - 1) & id_to_int(trace_id) # Use 64-bit trace id for trace in traces: - root = root_span(trace) - similarity = _span_similarity(root, span) - if similarity > max_similarity: - max_score_trace = trace - max_similarity = similarity - return max_score_trace + # This check ignores the high bits of the trace id + # TODO: Check _dd.p.tid + if trace and trace[0].get("trace_id") == trace_id: + return trace + raise AssertionError(f"Trace with 64bit trace_id={trace_id} not found. Traces={traces}") -def find_trace_by_root(traces: List[Trace], span: Span) -> Trace: - """Return the trace from `traces` with root span matching all fields of `span`.""" - trace = find_similar_trace_by_root(traces, span) - _assert_span_match(span, root_span(trace)) - return trace +def find_span(trace: Trace, span_id: int) -> Span: + """Return a span from the trace matches a `span_id`.""" + assert len(trace) > 0 + # TODO: Ensure all parametric applications return uint64 span ids (not strings) + span_id = id_to_int(span_id) + for span in trace: + if span.get("span_id") == span_id: + return span + raise AssertionError(f"Span with id={span_id} not found. Trace={trace}") -def find_similar_span(trace: Trace, span: Span) -> Span: - """Return a span from the trace which most closely matches `span`.""" - assert len(trace) > 0 +def find_span_in_traces(traces: list[Trace], trace_id: int, span_id: int) -> Span: + """Return a span from a list of traces by `trace_id` and `span_id`.""" + trace = find_trace(traces, trace_id) + return find_span(trace, span_id) - max_similarity = -math.inf - max_similarity_span = trace[0] - for other_span in trace: - similarity = _span_similarity(span, other_span) - if similarity > max_similarity: - max_similarity = similarity - max_similarity_span = other_span - return max_similarity_span +def find_only_span(traces: list[Trace]) -> Span: + """Return the only span in a list of traces. Raises an error if there are no traces or more than one span.""" + assert len(traces) == 1, traces + assert len(traces[0]) == 1, traces[0] + return traces[0][0] -def find_span(trace: Trace, span: Span) -> Span: - """Return a span from the trace matches all fields in `span`.""" - return _assert_span_match(span, find_similar_span(trace, span)) +def find_first_span_in_trace_payload(trace: Trace) -> Span: + """Return the first span recieved by the trace agent. This is not necessarily the root span.""" + # Note: Ensure traces are not sorted after receiving them from the agent. + # This helper will be used to find spans with propagation tags and some trace level tags + return trace[0] -def find_similar_span_in_traces(traces: List[Trace], span: Span) -> Span: - """Return a span from the traces which most closely matches `span`.""" - assert len(traces) > 0 - max_similarity = -math.inf - max_similarity_span = None - for trace in traces: - similar_span = find_similar_span(trace, span) - if max_similarity_span is None: - max_similarity_span = similar_span - similarity = _span_similarity(span, max_similarity_span) - if similarity > max_similarity: - max_similarity_span = similar_span - max_similarity = similarity - return max_similarity_span - - -def find_span_in_traces(traces: List[Trace], span: Span) -> Span: - """Return a span from the traces that matches all fields in `span`.""" - return _assert_span_match(span, find_similar_span_in_traces(traces, span)) - - -def _assert_span_match(span: Span, similar: Span) -> Span: - for var in Span.__annotations__: - if not var.startswith("__"): - val = span.get(var) - s_val = similar.get(var) - if val is not None and val != s_val: - # TODO remove this special handling once nodejs sets service in the same way. - # Right now, nodejs sets a tag named "service" in meta with the correct value. - if var == "service": - meta = similar.get("meta") - if meta is not None: - s_val = meta.get(var) - assert ( - val == s_val - ), f"Span field '{var}' mismatch '{val}' != '{s_val}'\nSpan : {span}\nSimilar: {similar}" - return similar +def find_root_span(trace: Trace) -> Span | None: + """Return the root span of the trace or None if no root span is found.""" + for span in trace: + if not span.get("parent_id"): + return span + return None def span_has_no_parent(span: Span) -> bool: @@ -262,14 +205,14 @@ def span_has_no_parent(span: Span) -> bool: return "parent_id" not in span or span.get("parent_id") == 0 or span.get("parent_id") is None -def assert_span_has_tags(span: Span, tags: Dict[str, Union[int, str, float, bool]]): +def assert_span_has_tags(span: Span, tags: dict[str, int | str | float | bool]): """Assert that the span has the given tags.""" for key, value in tags.items(): assert key in span.get("meta", {}), f"Span missing expected tag {key}={value}" assert span.get("meta", {}).get(key) == value, f"Span incorrect tag value for {key}={value}" -def assert_trace_has_tags(trace: Trace, tags: Dict[str, Union[int, str, float, bool]]): +def assert_trace_has_tags(trace: Trace, tags: dict[str, int | str | float | bool]): """Assert that the trace has the given tags.""" for span in trace: assert_span_has_tags(span, tags) @@ -279,25 +222,63 @@ def retrieve_span_links(span): if span.get("span_links") is not None: return span["span_links"] - if span["meta"].get("_dd.span_links") is not None: - # Convert span_links tags into msgpack v0.4 format - json_links = json.loads(span["meta"].get("_dd.span_links")) - links = [] - for json_link in json_links: - link = {} - link["trace_id"] = int(json_link["trace_id"][-16:], base=16) - link["span_id"] = int(json_link["span_id"], base=16) - if len(json_link["trace_id"]) > 16: - link["trace_id_high"] = int(json_link["trace_id"][:16], base=16) - if "attributes" in json_link: - link["attributes"] = json_link.get("attributes") - if "tracestate" in json_link: - link["tracestate"] = json_link.get("tracestate") - elif "trace_state" in json_link: - link["tracestate"] = json_link.get("trace_state") - if "flags" in json_link: - link["flags"] = json_link.get("flags") | TRACECONTEXT_FLAGS_SET - else: - link["flags"] = 0 - links.append(link) - return links + if span["meta"].get("_dd.span_links") is None: + return None + + # Convert span_links tags into msgpack v0.4 format + json_links = json.loads(span["meta"].get("_dd.span_links")) + links = [] + for json_link in json_links: + link = {} + link["trace_id"] = int(json_link["trace_id"][-16:], base=16) + link["span_id"] = int(json_link["span_id"], base=16) + if len(json_link["trace_id"]) > 16: + link["trace_id_high"] = int(json_link["trace_id"][:16], base=16) + if "attributes" in json_link: + link["attributes"] = json_link.get("attributes") + if "tracestate" in json_link: + link["tracestate"] = json_link.get("tracestate") + elif "trace_state" in json_link: + link["tracestate"] = json_link.get("trace_state") + if "flags" in json_link: + link["flags"] = json_link.get("flags") | TRACECONTEXT_FLAGS_SET + else: + link["flags"] = 0 + links.append(link) + return links + + +def retrieve_span_events(span): + if span.get("span_events") is not None: + return span["span_events"] + + if span["meta"].get("events") is None: + return None + + # Convert span_events tags into msgpack v0.4 format + json_events = json.loads(span["meta"].get("events")) + events = [] + for json_event in json_events: + event = {} + + event["time_unix_nano"] = json_event["time_unix_nano"] + event["name"] = json_event["name"] + if "attributes" in json_event: + event["attributes"] = json_event["attributes"] + + events.append(event) + return events + + +def id_to_int(value: str | int) -> int: + """Convert an id from hex or a base 10 string to an integer.""" + if isinstance(value, int): + return value + + try: + # This is a best effort to convert hex span/trace id to an integer. + # This is temporary solution until all parametric applications return trace/span ids + # as stringified integers (ids will be stringified to workaround percision issues in some languages) + return int(value) + except ValueError: + return int(value, 16) diff --git a/utils/parametric/spec/tracecontext.py b/utils/parametric/spec/tracecontext.py index 8b948d854b5..2b54c67d00f 100644 --- a/utils/parametric/spec/tracecontext.py +++ b/utils/parametric/spec/tracecontext.py @@ -86,11 +86,11 @@ class Tracestate: def __init__(self, *args, **kwds): if len(args) == 1 and not kwds: if isinstance(args[0], str): - self._traits = OrderedDict() + self._traits: OrderedDict = OrderedDict() self.from_string(args[0]) return if isinstance(args[0], Tracestate): - self._traits = OrderedDict(args[0]._traits) + self._traits = OrderedDict(args[0]._traits) # noqa: SLF001 return self._traits = OrderedDict(*args, **kwds) @@ -108,11 +108,11 @@ def __getitem__(self, key): def __setitem__(self, key, value): if not isinstance(key, str): - raise ValueError("key must be an instance of str") + raise TypeError("key must be an instance of str") if not re.match(self._KEY_VALIDATION_RE, key): raise ValueError("illegal key provided") if not isinstance(value, str): - raise ValueError("value must be an instance of str") + raise TypeError("value must be an instance of str") if not re.match(self._VALUE_VALIDATION_RE, value): raise ValueError("illegal value provided") self._traits[key] = value @@ -136,7 +136,7 @@ def from_string(self, string): return self def to_string(self): - return ",".join(map(lambda key: key + "=" + self[key], self._traits)) + return ",".join(key + "=" + self[key] for key in self._traits) def split(self, char=","): ts = self.to_string() @@ -152,9 +152,7 @@ def is_valid(self): if len(self.to_string()) > 512: return False # there can be a maximum of 32 list-members in a list - if len(self) > 32: - return False - return True + return not len(self) > 32 def pop(self): return self._traits.popitem() diff --git a/utils/parametric/test_agent.py b/utils/parametric/test_agent.py deleted file mode 100644 index 71d2f920019..00000000000 --- a/utils/parametric/test_agent.py +++ /dev/null @@ -1,4 +0,0 @@ -def get_span(test_agent): - traces = test_agent.wait_for_num_traces(num=1) - span = traces[0][0] - return span diff --git a/utils/properties_serialization.py b/utils/properties_serialization.py new file mode 100644 index 00000000000..836b895e564 --- /dev/null +++ b/utils/properties_serialization.py @@ -0,0 +1,112 @@ +import inspect +import json + +import pytest +from requests.structures import CaseInsensitiveDict + +from utils._weblog import HttpResponse, GrpcResponse, _Weblog +from utils.interfaces._core import InterfaceValidator +from utils.tools import logger + + +class _PropertiesEncoder(json.JSONEncoder): + def default(self, o): + if isinstance(o, CaseInsensitiveDict): + return dict(o.items()) + + if isinstance(o, (HttpResponse, GrpcResponse)): + return o.serialize() + + if isinstance(o, set): + return {"__class__": "set", "values": list(o)} + + # Let the base class default method raise the TypeError + return json.JSONEncoder.default(self, o) + + +class _PropertiesDecoder(json.JSONDecoder): + def __init__(self): + json.JSONDecoder.__init__(self, object_hook=_PropertiesDecoder.from_dict) + + @staticmethod + def from_dict(d): + if klass := d.get("__class__"): + if klass == "set": + return set(d["values"]) + + if klass == "GrpcResponse": + return GrpcResponse(d) + + if klass == "HttpResponse": + return HttpResponse(d) + + return d + + +class SetupProperties: + """Store all properties initialized by setup function, and dump =them into a file + In replay mode, it will restore then to the good instance + """ + + def __init__(self): + self._store = {} + + def store_properties(self, item: pytest.Item): + if properties := self._get_properties(item.instance): + self._store[item.nodeid] = properties + + def restore_properties(self, item: pytest.Item): + if properties := self._store.get(item.nodeid): + for name, value in properties.items(): + logger.debug(f"Restoring {name} for {item.nodeid}") + setattr(item.instance, name, value) + + @staticmethod + def _get_properties(instance) -> dict: + properties = { + name: getattr(instance, name) + for name in dir(instance) + if not name.startswith("_") and name not in ("pytestmark",) + } + + # removes methods, functions and computed properties + # also removes properties that already exists on the class + return { + name: value + for name, value in properties.items() + if not inspect.ismethod(value) + and not inspect.isfunction(value) + and not isinstance(getattr(type(instance), name, None), property) + and not isinstance(value, (_Weblog, InterfaceValidator)) # values that do not carry any tested data + } + + def dump(self, host_log_folder: str): + with open(f"{host_log_folder}/setup_properties.json", "w", encoding="utf-8") as f: + json.dump(self._store, f, indent=2, cls=_PropertiesEncoder) + + def load(self, host_log_folder: str): + filename = f"{host_log_folder}/setup_properties.json" + try: + with open(filename, encoding="utf-8") as f: + self._store = json.load(f, cls=_PropertiesDecoder) + except FileNotFoundError: + pytest.exit(f"{filename} does not exists. Did you run the tests without any INTERNALERROR output?") + + def log_requests(self, item: pytest.Item) -> None: + if properties := self._store.get(item.nodeid): + self._log_requests(properties) + + def _log_requests(self, o) -> None: + if isinstance(o, HttpResponse): + logger.info(f"weblog {o.request.method} {o.request.url} -> {o.status_code}") + elif isinstance(o, GrpcResponse): + logger.info("weblog GRPC request") + elif isinstance(o, dict): + self._log_requests(list(o.values())) + elif isinstance(o, list): + for value in o: + self._log_requests(value) + + +if __name__ == "__main__": + SetupProperties().load("logs") diff --git a/utils/proxy/__init__.py b/utils/proxy/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/proxy/_decoders/__init__.py b/utils/proxy/_decoders/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/proxy/_decoders/protobuf_schemas.py b/utils/proxy/_decoders/protobuf_schemas.py index 80d3aaa8238..f0b4a9ce837 100644 --- a/utils/proxy/_decoders/protobuf_schemas.py +++ b/utils/proxy/_decoders/protobuf_schemas.py @@ -10,9 +10,9 @@ with open(Path(__file__).parent / "agent.descriptor", "rb") as f: _fds = FileDescriptorSet.FromString(f.read()) -_messages = GetMessages([file for file in _fds.file]) +_messages = GetMessages(list(_fds.file)) -print(f"Message types present in protobuf descriptors: {_messages.keys()}") +print(f"Message types present in protobuf descriptors: {_messages.keys()}") # noqa: T201 TracePayload = _messages["datadog.trace.AgentPayload"] MetricPayload = _messages["datadog.agentpayload.MetricPayload"] diff --git a/utils/proxy/_deserializer.py b/utils/proxy/_deserializer.py index 64c6c80d102..204fb70b9ef 100644 --- a/utils/proxy/_deserializer.py +++ b/utils/proxy/_deserializer.py @@ -2,10 +2,13 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. +from ast import literal_eval import base64 import gzip +import io import json import logging +from hashlib import md5 import traceback import msgpack @@ -34,18 +37,19 @@ def get_header_value(name, headers): def _parse_as_unsigned_int(value, size_in_bits): - """This is necessary because some fields in spans are decribed as a 64 bits unsigned integers, but + """Some fields in spans are decribed as a 64 bits unsigned integers, but java, and other languages only supports signed integer. As such, they might send trace ids as negative number if >2**63 -1. The agent parses it signed and interpret the bytes as unsigned. See - https://github.com/DataDog/datadog-agent/blob/778855c6c31b13f9235a42b758a1f7c8ab7039e5/pkg/trace/pb/decoder_bytes.go#L181-L196""" + https://github.com/DataDog/datadog-agent/blob/778855c6c31b13f9235a42b758a1f7c8ab7039e5/pkg/trace/pb/decoder_bytes.go#L181-L196 + """ if not isinstance(value, int): return value # Asserts that the unsigned is either a no bigger than the size in bits - assert -(2 ** size_in_bits - 1) <= value <= 2 ** size_in_bits - 1 + assert -(2**size_in_bits - 1) <= value <= 2**size_in_bits - 1 # Take two's complement of the number if negative - return value if value >= 0 else (-value ^ (2 ** size_in_bits - 1)) + 1 + return value if value >= 0 else (-value ^ (2**size_in_bits - 1)) + 1 def _decode_unsigned_int_traces(content): @@ -85,7 +89,7 @@ def _decode_v_0_5_traces(content): def deserialize_dd_appsec_s_meta(payload): - """ meta value for _dd.appsec.s.
are b64 - gzip - json encoded strings """ + """Meta value for _dd.appsec.s.
are b64 - gzip - json encoded strings""" try: return json.loads(gzip.decompress(base64.b64decode(payload)).decode()) @@ -94,35 +98,36 @@ def deserialize_dd_appsec_s_meta(payload): return json.loads(payload) -def deserialize_http_message(path, message, content: bytes, interface, key): +def deserialize_http_message(path, message, content: bytes, interface, key, export_content_files_to: str): def json_load(): if not content: return None return json.loads(content) - content_type = get_header_value("content-type", message["headers"]) - content_type = None if content_type is None else content_type.lower() + raw_content_type = get_header_value("content-type", message["headers"]) + content_type = None if raw_content_type is None else raw_content_type.lower() - if content_type and any((mime_type in content_type for mime_type in ("application/json", "text/json"))): + if not content or len(content) == 0: + return None + + if content_type and any(mime_type in content_type for mime_type in ("application/json", "text/json")): return json_load() if path == "/v0.7/config": # Kyle, please add content-type header :) if key == "response" and message["status_code"] == 404: return content.decode(encoding="utf-8") - else: - return json_load() + + return json_load() if interface == "library" and path == "/info": if key == "response": return json_load() - else: - if not content: - return None - else: - return content - if content_type in ("application/msgpack", "application/msgpack, application/msgpack"): + # replace zero length strings/bytes by None + return content if content else None + + if content_type in ("application/msgpack", "application/msgpack, application/msgpack") or (path == "/v0.6/stats"): result = msgpack.unpackb(content, unicode_errors="replace", strict_map_key=False) if interface == "library": @@ -135,13 +140,19 @@ def json_load(): _decode_unsigned_int_traces(result) _deserialized_nested_json_from_trace_payloads(result, interface) + elif path == "/v0.6/stats": + # TODO : more strange stuff inside to deserialize + # ddsketch protobuf in content.stats[].stats.OkSummary and ErrorSummary + # https://github.com/DataDog/sketches-go/blob/master/ddsketch/pb/ddsketch.proto#L15 + pass + _convert_bytes_values(result) return result if content_type == "application/x-protobuf": # Raw data can be either a str like "b'\n\x\...'" or bytes - content = eval(content) if isinstance(content, str) else content + content = literal_eval(content) if isinstance(content, str) else content assert isinstance(content, bytes) dd_protocol = get_header_value("dd-protocol", message["headers"]) if dd_protocol == "otlp" and "traces" in path: @@ -168,37 +179,77 @@ def json_load(): if content_type and content_type.startswith("multipart/form-data;"): decoded = [] - for part in MultipartDecoder(content, content_type).parts: + for part in MultipartDecoder(content, raw_content_type).parts: headers = {k.decode("utf-8"): v.decode("utf-8") for k, v in part.headers.items()} item = {"headers": headers} - try: - item["content"] = part.text - except UnicodeDecodeError: - item["content"] = part.content - decoded.append(item) + content_type_part = "" - if path == "/debugger/v1/diagnostics": - for item in decoded: - if "content" in item: - try: - item["content"] = json.loads(item["content"]) - except: - pass + for name, value in headers.items(): + if name.lower() == "content-type": + content_type_part = value.lower() + break + + if content_type_part.startswith("application/json"): + item["content"] = json.loads(part.content) + + elif content_type_part == "application/gzip": + with gzip.GzipFile(fileobj=io.BytesIO(part.content)) as gz_file: + content = gz_file.read() + + _deserialize_file_in_multipart_form_data(item, headers, export_content_files_to, content) + + elif content_type_part == "application/octet-stream": + _deserialize_file_in_multipart_form_data(item, headers, export_content_files_to, part.content) + + else: + try: + item["content"] = part.text + except UnicodeDecodeError: + item["content"] = str(part.content) + + decoded.append(item) return decoded if content_type == "text/plain": return content.decode("ascii") - if not content or len(content) == 0: - return None - return content +def _deserialize_file_in_multipart_form_data( + item: dict, headers: dict, export_content_files_to: str, content: bytes +) -> None: + content_disposition = headers.get("Content-Disposition", "") + + if not content_disposition.startswith("form-data"): + item["system-tests-error"] = "Unknown content-disposition, please contact #apm-shared-testing" + item["content"] = None + + else: + meta_data = {} + + for part in content_disposition.split(";"): + if "=" in part: + key, value = part.split("=", 1) + meta_data[key.strip()] = value.strip() + + if "filename" not in meta_data: + item["system-tests-error"] = "Filename not found in content-disposition, please contact #apm-shared-testing" + else: + filename = meta_data["filename"].strip('"') + file_path = f"{export_content_files_to}/{md5(content).hexdigest()}_{filename}" + + with open(file_path, "wb") as f: + f.write(content) + + item["system-tests-information"] = "File exported to a separated file" + item["system-tests-file-path"] = file_path + + def _deserialized_nested_json_from_trace_payloads(content, interface): - """ trace payload from agent and library contains strings that are json """ + """Trace payload from agent and library contains strings that are json""" if interface == "agent": for tracer_payload in content.get("tracerPayloads", []): @@ -213,7 +264,6 @@ def _deserialized_nested_json_from_trace_payloads(content, interface): def _deserialize_meta(span): - meta = span.get("meta", {}) keys = ("_dd.appsec.json", "_dd.iast.json") @@ -248,12 +298,13 @@ def _convert_bytes_values(item, path=""): _convert_bytes_values(value, f"{path}[]") -def deserialize(data, key, content, interface): - +def deserialize(data, key, content, interface, export_content_files_to: str): try: - data[key]["content"] = deserialize_http_message(data["path"], data[key], content, interface, key) + data[key]["content"] = deserialize_http_message( + data["path"], data[key], content, interface, key, export_content_files_to + ) except: - logger.exception(f"Error while deserializing {data['log_filename']}", exc_info=True) + logger.exception(f"Error while deserializing {data['log_filename']}") data[key]["raw_content"] = str(content) data[key]["traceback"] = str(traceback.format_exc()) diff --git a/utils/proxy/core.py b/utils/proxy/core.py index 87bc351b451..58107013d7e 100644 --- a/utils/proxy/core.py +++ b/utils/proxy/core.py @@ -3,32 +3,39 @@ import json import logging import os -from datetime import datetime +from datetime import datetime, UTC from mitmproxy import master, options, http from mitmproxy.addons import errorcheck, default_addons from mitmproxy.flow import Error as FlowError, Flow -import rc_debugger -from rc_mock import MOCKED_RESPONSES from _deserializer import deserialize +from ports import ProxyPorts # prevent permission issues on file created by the proxy when the host is linux os.umask(0) logger = logging.getLogger(__name__) -handler = logging.StreamHandler() -handler.setLevel(logging.DEBUG) -handler.setFormatter(logging.Formatter("%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s", "%H:%M:%S")) -logger.addHandler(handler) -logger.setLevel(logging.DEBUG) SIMPLE_TYPES = (bool, int, float, type(None)) - messages_counts = defaultdict(int) +class CustomFormatter(logging.Formatter): + def __init__(self, keys: list[str], *args, **kwargs) -> None: + super().__init__(*args, **kwargs) + self._keys = keys + + def format(self, record): + result = super().format(record) + + for key in self._keys: + result = result.replace(key, "{redacted-by-system-tests-proxy}") + + return result + + class ObjectDumpEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, bytes): @@ -38,33 +45,42 @@ def default(self, o): class _RequestLogger: def __init__(self) -> None: - self.dd_api_key = os.environ["DD_API_KEY"] - self.dd_application_key = os.environ.get("DD_APPLICATION_KEY") - self.dd_app_key = os.environ.get("DD_APP_KEY") - self.state = json.loads(os.environ.get("PROXY_STATE", "{}")) + self._keys = [ + os.environ.get("DD_API_KEY"), + os.environ.get("DD_APPLICATION_KEY"), + os.environ.get("DD_APP_KEY"), + ] + + self._keys = [key for key in self._keys if key is not None] + + handler = logging.StreamHandler() + handler.setLevel(logging.DEBUG) + formatter = CustomFormatter( + fmt="%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s", datefmt="%H:%M:%S", keys=self._keys + ) + handler.setFormatter(formatter) + logger.addHandler(handler) + logger.setLevel(logging.DEBUG) + self.host_log_folder = os.environ.get("SYSTEM_TESTS_HOST_LOG_FOLDER", "logs") - # for config backend mock - self.config_request_count = defaultdict(int) + self.rc_api_enabled = os.environ.get("SYSTEM_TESTS_RC_API_ENABLED") == "True" + self.span_meta_structs_disabled = os.environ.get("SYSTEM_TESTS_AGENT_SPAN_META_STRUCTS_DISABLED") == "True" - logger.debug(f"Proxy state: {self.state}") + span_events = os.environ.get("SYSTEM_TESTS_AGENT_SPAN_EVENTS") + self.span_events = span_events != "False" - # request -> original port - # as the port is overwritten at request stage, we loose it on response stage - # this property will keep it - self.original_ports = {} + self.rc_api_command = None - self.rc_api_enabled = os.environ.get("RC_API_ENABLED") == "True" - self.rc_api_payload = None - self.rc_api_runtime_ids_applied = set() + # mimic the old API + self.rc_api_sequential_commands = None + self.rc_api_runtime_ids_request_count = None def _scrub(self, content): if isinstance(content, str): - content = content.replace(self.dd_api_key, "{redacted-by-system-tests-proxy}") - if self.dd_app_key: - content = content.replace(self.dd_app_key, "{redacted-by-system-tests-proxy}") - if self.dd_application_key: - content = content.replace(self.dd_application_key, "{redacted-by-system-tests-proxy}") + for key in self._keys: + content = content.replace(key, "{redacted-by-system-tests-proxy}") + return content if isinstance(content, (list, set, tuple)): @@ -85,60 +101,78 @@ def get_error_response(message): return http.Response.make(400, message) def request(self, flow: Flow): + # sockname is the local address (host, port) we received this connection on. + port = flow.client_conn.sockname[1] - logger.info(f"{flow.request.method} {flow.request.pretty_url}") + logger.info(f"{flow.request.method} {flow.request.pretty_url}, using proxy port {port}") - if flow.request.port == 11111: - if len(self.state) != 0: - flow.response = self.get_error_response(b"Can't use RC API with a proxy state") - elif not self.rc_api_enabled: + if port == ProxyPorts.proxy_commands: + if not self.rc_api_enabled: flow.response = self.get_error_response(b"RC API is not enabled") - else: - logger.info("Store RC response to mock") - self.rc_api_payload = flow.request.content - self.rc_api_runtime_ids_applied.clear() + elif flow.request.path == "/unique_command": + logger.info("Store RC command to mock") + self.rc_api_command = flow.request.content + flow.response = http.Response.make(200, b"Ok") + elif flow.request.path == "/sequential_commands": + logger.info("Reset mocked RC sequential commands") + self.rc_api_sequential_commands = json.loads(flow.request.content) + self.rc_api_runtime_ids_request_count = defaultdict(int) flow.response = http.Response.make(200, b"Ok") + else: + flow.response = http.Response.make(404, b"Not found") return - self.original_ports[flow.id] = flow.request.port - - if flow.request.host in ("proxy", "localhost"): - # tracer is the only container that uses the proxy directly - - if flow.request.headers.get("dd-protocol") == "otlp": - # OTLP ingestion - otlp_path = flow.request.headers.get("dd-otlp-path") - if otlp_path == "agent": - flow.request.host = "agent" - flow.request.port = 4318 - flow.request.scheme = "http" - elif otlp_path == "collector": - flow.request.host = "system-tests-collector" - flow.request.port = 4318 - flow.request.scheme = "http" - elif otlp_path == "intake-traces": - flow.request.host = "trace.agent." + os.environ.get("DD_SITE", "datad0g.com") - flow.request.port = 443 - flow.request.scheme = "https" - elif otlp_path == "intake-metrics": - flow.request.host = "api." + os.environ.get("DD_SITE", "datad0g.com") - flow.request.port = 443 - flow.request.scheme = "https" - else: - raise Exception(f"Unknown OTLP ingestion path {otlp_path}") - else: - flow.request.host, flow.request.port = "agent", 8127 + # if flow.request.headers.get("dd-protocol") == "otlp": + if port == ProxyPorts.open_telemetry_weblog: + # OTLP ingestion + otlp_path = flow.request.headers.get("dd-otlp-path") + if otlp_path == "agent": + flow.request.host = "agent" + flow.request.port = 4318 flow.request.scheme = "http" + elif otlp_path == "collector": + flow.request.host = "system-tests-collector" + flow.request.port = 4318 + flow.request.scheme = "http" + elif otlp_path == "intake-traces": + flow.request.host = "trace.agent." + os.environ.get("DD_SITE", "datad0g.com") + flow.request.port = 443 + flow.request.scheme = "https" + elif otlp_path == "intake-metrics": + flow.request.host = "api." + os.environ.get("DD_SITE", "datad0g.com") + flow.request.port = 443 + flow.request.scheme = "https" + elif otlp_path == "intake-logs": + flow.request.host = "http-intake.logs." + os.environ.get("DD_SITE", "datad0g.com") + flow.request.port = 443 + flow.request.scheme = "https" + else: + raise ValueError(f"Unknown OTLP ingestion path {otlp_path}") logger.info(f" => reverse proxy to {flow.request.pretty_url}") + elif port in ( + ProxyPorts.python_buddy, + ProxyPorts.nodejs_buddy, + ProxyPorts.java_buddy, + ProxyPorts.ruby_buddy, + ProxyPorts.golang_buddy, + ProxyPorts.weblog, + ): + flow.request.host, flow.request.port = "agent", 8127 + flow.request.scheme = "http" + logger.info(f" => reverse proxy to {flow.request.pretty_url}") + @staticmethod def request_is_from_tracer(request): return request.host == "agent" def response(self, flow): - if flow.request.port == 11111: + # sockname is the local address (host, port) we received this connection on. + port = flow.client_conn.sockname[1] + + if port == ProxyPorts.proxy_commands: return try: @@ -147,28 +181,24 @@ def response(self, flow): self._modify_response(flow) # get the interface name - if flow.request.headers.get("dd-protocol") == "otlp": + if port == ProxyPorts.open_telemetry_weblog: interface = "open_telemetry" - elif self.request_is_from_tracer(flow.request): - port = self.original_ports[flow.id] - if port == 8126: - interface = "library" - elif port == 80: # UDS mode - interface = "library" - elif port == 9001: - interface = "python_buddy" - elif port == 9002: - interface = "nodejs_buddy" - elif port == 9003: - interface = "java_buddy" - elif port == 9004: - interface = "ruby_buddy" - elif port == 9005: - interface = "golang_buddy" - else: - raise ValueError(f"Unknown port provenance for {flow.request}: {port}") - else: + elif port == ProxyPorts.weblog: + interface = "library" + elif port == ProxyPorts.python_buddy: + interface = "python_buddy" + elif port == ProxyPorts.nodejs_buddy: + interface = "nodejs_buddy" + elif port == ProxyPorts.java_buddy: + interface = "java_buddy" + elif port == ProxyPorts.ruby_buddy: + interface = "ruby_buddy" + elif port == ProxyPorts.golang_buddy: + interface = "golang_buddy" + elif port == ProxyPorts.agent: # HTTPS port, as the agent use the proxy with HTTP_PROXY env var interface = "agent" + else: + raise ValueError(f"Unknown port provenance for {flow.request}: {port}") # extract url info if "?" in flow.request.path: @@ -180,6 +210,7 @@ def response(self, flow): message_count = messages_counts[interface] messages_counts[interface] += 1 log_foldename = f"{self.host_log_folder}/interfaces/{interface}" + export_content_files_to = f"{log_foldename}/files" log_filename = f"{log_foldename}/{message_count:05d}_{path.replace('/', '_')}.json" data = { @@ -189,7 +220,7 @@ def response(self, flow): "host": flow.request.host, "port": flow.request.port, "request": { - "timestamp_start": datetime.fromtimestamp(flow.request.timestamp_start).isoformat(), + "timestamp_start": datetime.fromtimestamp(flow.request.timestamp_start, tz=UTC).isoformat(), "headers": list(flow.request.headers.items()), "length": len(flow.request.content) if flow.request.content else 0, }, @@ -200,12 +231,24 @@ def response(self, flow): }, } - deserialize(data, key="request", content=flow.request.content, interface=interface) + deserialize( + data, + key="request", + content=flow.request.content, + interface=interface, + export_content_files_to=export_content_files_to, + ) if flow.error and flow.error.msg == FlowError.KILLED_MESSAGE: data["response"] = None else: - deserialize(data, key="response", content=flow.response.content, interface=interface) + deserialize( + data, + key="response", + content=flow.response.content, + interface=interface, + export_content_files_to=export_content_files_to, + ) try: data = self._scrub(data) @@ -221,68 +264,48 @@ def response(self, flow): logger.exception("Unexpected error") def _modify_response(self, flow): - if len(self.state) != 0: - rc_config = self.state.get("mock_remote_config_backend") - if rc_config is None: - return - mocked_responses = MOCKED_RESPONSES.get(rc_config) - if mocked_responses is None: - return - self._modify_response_rc(flow, mocked_responses) + if self.request_is_from_tracer(flow.request): + if self.rc_api_enabled: + self._add_rc_capabilities_in_info_request(flow) - elif self.rc_api_enabled and self.request_is_from_tracer(flow.request): - self._add_rc_capabilities_in_info_request(flow) + if flow.request.path == "/v0.7/config": + # mimic the default response from the agent + flow.response.status_code = 200 + flow.response.content = b"{}" + flow.response.headers["Content-Type"] = "application/json" - if flow.request.path == "/v0.7/config" and self.rc_api_payload is not None: - request_content = json.loads(flow.request.content) - runtime_id = request_content["client"]["client_tracer"]["runtime_id"] + if self.rc_api_command is not None: + request_content = json.loads(flow.request.content) + logger.info(" => modifying rc response") + flow.response.content = self.rc_api_command - if runtime_id in self.rc_api_runtime_ids_applied: - # this runtime id has already been applied - return + elif self.rc_api_sequential_commands is not None: + request_content = json.loads(flow.request.content) + runtime_id = request_content["client"]["client_tracer"]["runtime_id"] + nth_api_command = self.rc_api_runtime_ids_request_count[runtime_id] + response = self.rc_api_sequential_commands[nth_api_command] - logger.info(f" => modifying rc response for runtime ID {runtime_id}") + logger.info(f" => Modifying RC response for runtime ID {runtime_id}") + logger.info(f" => Overwriting /v0.7/config response #{nth_api_command}") - flow.response.status_code = 200 - flow.response.content = self.rc_api_payload + flow.response.content = json.dumps(response).encode() + flow.response.headers["st-proxy-overwrite-rc-response"] = f"{nth_api_command}" - self.rc_api_runtime_ids_applied.add(runtime_id) + if nth_api_command + 1 < len(self.rc_api_sequential_commands): + self.rc_api_runtime_ids_request_count[runtime_id] = nth_api_command + 1 - def _modify_response_rc(self, flow, mocked_responses): - if not self.request_is_from_tracer(flow.request): - return # modify only tracer/agent flow + if self.span_meta_structs_disabled: + self._remove_meta_structs_support(flow) - self._add_rc_capabilities_in_info_request(flow) + self._modify_span_events_flag(flow) - if flow.request.path == "/v0.7/config": - request_content = json.loads(flow.request.content) - - runtime_id = request_content["client"]["client_tracer"]["runtime_id"] - logger.info(f" => modifying rc response for runtime ID {runtime_id}") - logger.info(f" => Overwriting /v0.7/config response #{self.config_request_count[runtime_id] + 1}") - - if self.config_request_count[runtime_id] + 1 > len(mocked_responses): - response = {} # default content when there isn't an RC update - else: - if self.state.get("mock_remote_config_backend") in ( - "DEBUGGER_PROBES_STATUS", - "DEBUGGER_LINE_PROBES_SNAPSHOT", - "DEBUGGER_METHOD_PROBES_SNAPSHOT", - "DEBUGGER_MIX_LOG_PROBE", - "DEBUGGER_EXPRESSION_LANGUAGE", - ): - response = rc_debugger.create_rcm_probe_response( - request_content["client"]["client_tracer"]["language"], - mocked_responses[self.config_request_count[runtime_id]], - self.config_request_count[runtime_id], - ) - else: - response = mocked_responses[self.config_request_count[runtime_id]] - - flow.response.status_code = 200 - flow.response.content = json.dumps(response).encode() - - self.config_request_count[runtime_id] += 1 + def _remove_meta_structs_support(self, flow): + if flow.request.path == "/info" and str(flow.response.status_code) == "200": + c = json.loads(flow.response.content) + if "span_meta_structs" in c: + logger.info(" => Overwriting /info response to remove span_meta_structs field") + c.pop("span_meta_structs") + flow.response.content = json.dumps(c).encode() def _add_rc_capabilities_in_info_request(self, flow): if flow.request.path == "/info" and str(flow.response.status_code) == "200": @@ -293,23 +316,38 @@ def _add_rc_capabilities_in_info_request(self, flow): c["endpoints"].append("/v0.7/config") flow.response.content = json.dumps(c).encode() + def _modify_span_events_flag(self, flow): + """Modify the agent flag that signals support for native span event serialization. + There are three possible cases: + - Not configured: agent's response is not modified, the real agent behavior is preserved + - `true`: agent advertises support for native span events serialization + - `false`: agent advertises that it does not support native span events serialization + """ + if flow.request.path == "/info" and str(flow.response.status_code) == "200": + c = json.loads(flow.response.content) + c["span_events"] = self.span_events + flow.response.content = json.dumps(c).encode() -def start_proxy() -> None: - # the port is used to make the distinction between weblogs (See CROSSED_TRACING_LIBRARIES scenario) +def start_proxy() -> None: + # the port is used to make the distinction between provenance + # not that backend is not needed as it's used with HTTP_PROXY modes = [ - "regular@8126", # base weblog - "regular@9001", # python_buddy - "regular@9002", # nodejs_buddy - "regular@9003", # java_buddy - "regular@9004", # ruby_buddy - "regular@9005", # golang_buddy - "regular@11111", # RC payload API + f"regular@{ProxyPorts.proxy_commands}", # RC payload API + f"regular@{ProxyPorts.weblog}", # base weblog + f"regular@{ProxyPorts.python_buddy}", # python_buddy + f"regular@{ProxyPorts.nodejs_buddy}", # nodejs_buddy + f"regular@{ProxyPorts.java_buddy}", # java_buddy + f"regular@{ProxyPorts.ruby_buddy}", # ruby_buddy + f"regular@{ProxyPorts.golang_buddy}", # golang_buddy + f"regular@{ProxyPorts.open_telemetry_weblog}", # Open telemetry weblog + f"regular@{ProxyPorts.agent}", # from agent to backend ] loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) - opts = options.Options(mode=modes, listen_host="0.0.0.0", confdir="utils/proxy/.mitmproxy") + listen_host = "::" if os.environ.get("SYSTEM_TESTS_IPV6") == "True" else "0.0.0.0" # noqa: S104 + opts = options.Options(mode=modes, listen_host=listen_host, confdir="utils/proxy/.mitmproxy") proxy = master.Master(opts, event_loop=loop) proxy.addons.add(*default_addons()) proxy.addons.add(errorcheck.ErrorCheck()) diff --git a/utils/proxy/ports.py b/utils/proxy/ports.py new file mode 100644 index 00000000000..489beb3f92b --- /dev/null +++ b/utils/proxy/ports.py @@ -0,0 +1,18 @@ +from enum import IntEnum + + +class ProxyPorts(IntEnum): + """Proxy port are used by the proxy to determine the provenance of the request""" + + proxy_commands = 11111 + + weblog = 8126 + open_telemetry_weblog = 8127 + + agent = 8200 + + python_buddy = 9001 + nodejs_buddy = 9002 + java_buddy = 9003 + ruby_buddy = 9004 + golang_buddy = 9005 diff --git a/utils/proxy/rc_debugger.py b/utils/proxy/rc_debugger.py deleted file mode 100644 index 6ebe52b810f..00000000000 --- a/utils/proxy/rc_debugger.py +++ /dev/null @@ -1,102 +0,0 @@ -import json -import base64 -import copy -import os -import os.path -import hashlib - - -_CUR_DIR = os.path.dirname(os.path.abspath(__file__)) - - -with open(os.path.join(_CUR_DIR, "debugger/base_target.json"), "r", encoding="utf-8") as f: - _BASE_TARGET = json.load(f) - -with open(os.path.join(_CUR_DIR, "debugger/base_signed.json"), "r", encoding="utf-8") as f: - _BASE_SIGNED = json.load(f) - -with open(os.path.join(_CUR_DIR, "debugger/base_target_file.json"), "r", encoding="utf-8") as f: - _BASE_TARGET_FILE = json.load(f) - -with open(os.path.join(_CUR_DIR, "debugger/base_rcm.json"), "r", encoding="utf-8") as f: - _BASE_RCM = json.load(f) - - -def create_rcm_probe_response(library, probes, version): - def _json_to_base64(json_object): - json_string = json.dumps(json_object).encode("utf-8") - base64_string = base64.b64encode(json_string).decode("utf-8") - return base64_string - - def _sha256(str): - bytes = base64.b64decode(str) - return hashlib.sha256(bytes).hexdigest() - - def _get_probe_type(probe_id): - if probe_id.startswith("log"): - return "logProbe" - elif probe_id.startswith("metric"): - return "metricProbe" - elif probe_id.startswith("span"): - return "spanProbe" - elif probe_id.startswith("decor"): - return "spanDecorationProbe" - else: - return "not_supported" - - rcm = copy.deepcopy(_BASE_RCM) - signed = copy.deepcopy(_BASE_SIGNED) - signed["signed"]["version"] = version - - if probes is None: - rcm["targets"] = _json_to_base64(signed) - else: - for probe in probes: - target = copy.deepcopy(_BASE_TARGET) - target_file = copy.deepcopy(_BASE_TARGET_FILE) - - probe["language"] = library - - if probe["where"]["typeName"] == "ACTUAL_TYPE_NAME": - if library == "dotnet": - probe["where"]["typeName"] = "weblog.DebuggerController" - elif library == "java": - probe["where"]["typeName"] = "DebuggerController" - probe["where"]["methodName"] = ( - probe["where"]["methodName"][0].lower() + probe["where"]["methodName"][1:] - ) - elif probe["where"]["sourceFile"] == "ACTUAL_SOURCE_FILE": - if library == "dotnet": - probe["where"]["sourceFile"] = "DebuggerController.cs" - elif library == "java": - probe["where"]["sourceFile"] = "DebuggerController.java" - - probe_64 = _json_to_base64(probe) - type = _get_probe_type(probe["id"]) - path = "datadog/2/LIVE_DEBUGGING/" + type + "_" + probe["id"] + "/config" - - target["hashes"]["sha256"] = _sha256(probe_64) - target["length"] = len(json.dumps(probe).encode("utf-8")) - signed["signed"]["targets"][path] = target - - target_file["path"] = path - target_file["raw"] = probe_64 - - rcm["target_files"].append(target_file) - rcm["client_configs"].append(path) - - rcm["targets"] = _json_to_base64(signed) - return rcm - - -if __name__ == "__main__": - # utility to generate a mocked response for a specific probe, to help RC API migration - from utils.proxy.rc_mock import MOCKED_RESPONSES - - rc_config = "DEBUGGER_PII_REDACTION" - mocked_responses = MOCKED_RESPONSES.get(rc_config) - - i = 1 - payload = create_rcm_probe_response(library="java", probes=mocked_responses[i], version=i) - print(mocked_responses[i]) - print(payload) diff --git a/utils/proxy/rc_mock.py b/utils/proxy/rc_mock.py deleted file mode 100644 index b802a384f07..00000000000 --- a/utils/proxy/rc_mock.py +++ /dev/null @@ -1,16 +0,0 @@ -import json -import os -import os.path - -_CUR_DIR = os.path.dirname(os.path.abspath(__file__)) - -MOCKED_RESPONSES = {} - -for path in os.listdir(_CUR_DIR): - if not path.startswith("rc_mocked_responses_"): - continue - if not path.endswith(".json"): - continue - scenario_name = path.replace("rc_mocked_responses_", "").replace(".json", "").upper() - with open(os.path.join(_CUR_DIR, path), encoding="utf-8") as f: - MOCKED_RESPONSES[scenario_name] = json.load(f) diff --git a/utils/proxy/rc_mocked_responses_appsec_api_security_rc.json b/utils/proxy/rc_mocked_responses_appsec_api_security_rc.json deleted file mode 100644 index 305773b0362..00000000000 --- a/utils/proxy/rc_mocked_responses_appsec_api_security_rc.json +++ /dev/null @@ -1,24 +0,0 @@ -[ - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvQVNNL0FTTS1iYXNlL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiIxYjdmZjIzZTNhN2NiODBiNTBjZjE3ZmM4ZmU4ZTk2MmY5OTFmOTY3YWFkYzViMTE3NWI5ODJjN2RhZTRlOTI3In0sImxlbmd0aCI6ODYwfSwiZGF0YWRvZy8yL0FTTV9ERC9BU01fREQtYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiYmM3ZTg2NzRjZTE3MzY1NzZlYTUwZWYyZDJhOTgxY2MwYzEwZDIxZDk4ODA0MWI0ZWRhZDA3YjBhYzYwMWI4OCJ9LCJsZW5ndGgiOjI4NTR9LCJkYXRhZG9nLzIvQVNNX0ZFQVRVUkVTL0FTTV9GRUFUVVJFUy1iYXNlL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJjODg4ZDFmYTQzOTAwNTlkMWI1NGJlMGEwMjNkY2UyOTMyOWM0ZGM0OThiZmQxMDQyZDlhZmM3MWM2M2QyNWRhIn0sImxlbmd0aCI6MTExfX0sInZlcnNpb24iOjJ9LCJzaWduYXR1cmVzIjpbeyJrZXlpZCI6ImVkNzY3MmM5YTI0YWJkYTc4ODcyZWUzMmVlNzFjN2NiMWQ1MjM1ZThkYjRlY2JmMWNhMjhiOWM1MGViNzVkOWUiLCJzaWciOiI3YTE3ZGYzZWQ2NjJhMmU1YjgwNDAzNTE4ZGU1NDVjMjUwNDQ1OWI0YzFhN2E2NTY0MTg4ZDhmZjZkMDY2NDk0MGE5NTlhYjRjMDIyYThlMWJiZmZlMTU3ODVhOTA5OGYwYmQxNTcwODlhNTgwYzhlNGY1OWVjYmZjNTNiNDEwNCJ9XX0=", - "target_files": [ - { - "path": "datadog/2/ASM_FEATURES/ASM_FEATURES-base/config", - "raw": "ewogICAgImFzbSI6IHsKICAgICAgICAiZW5hYmxlZCI6IHRydWUKICAgIH0sCiAgICAiYXBpX3NlY3VyaXR5IjogewogICAgICAgICJyZXF1ZXN0X3NhbXBsZV9yYXRlIjogMS4wCiAgICB9Cn0K" - }, - { - "path": "datadog/2/ASM_DD/ASM_DD-base/config", - "raw": "ewogICAgInZlcnNpb24iOiAiMi4yIiwKICAgICJtZXRhZGF0YSI6IHsKICAgICAgInJ1bGVzX3ZlcnNpb24iOiAiMS4xMC4wIgogICAgfSwKICAgICJydWxlcyI6IFsKICAgICAgewogICAgICAgICJpZCI6ICJ0ZXN0LTAwMSIsCiAgICAgICAgIm5hbWUiOiAiVGVzdCAwMDEgcnVsZSIsCiAgICAgICAgInRhZ3MiOiB7CiAgICAgICAgICAidHlwZSI6ICJjb21tZXJjaWFsX3NjYW5uZXIiLAogICAgICAgICAgImNhdGVnb3J5IjogImF0dGFja19hdHRlbXAiCiAgICAgICAgfSwKICAgICAgICAiY29uZGl0aW9ucyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgInBhcmFtZXRlcnMiOiB7CiAgICAgICAgICAgICAgImlucHV0cyI6IFsKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImFkZHJlc3MiOiAic2VydmVyLnJlcXVlc3QucXVlcnkiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAiYWRkcmVzcyI6ICJzZXJ2ZXIucmVxdWVzdC51cmkucmF3IgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgImFkZHJlc3MiOiAic2VydmVyLnJlcXVlc3QuYm9keSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICJyZWdleCI6ICJ0ZXN0YXR0YWNrIiwKICAgICAgICAgICAgICAib3B0aW9ucyI6IHsKICAgICAgICAgICAgICAgICJjYXNlX3NlbnNpdGl2ZSI6IGZhbHNlCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICAib3BlcmF0b3IiOiAibWF0Y2hfcmVnZXgiCiAgICAgICAgICB9CiAgICAgICAgXQogICAgICB9CiAgICBdLAogICAgInByb2Nlc3NvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaWQiOiAiZXh0cmFjdC1jb250ZW50IiwKICAgICAgICAiZ2VuZXJhdG9yIjogImV4dHJhY3Rfc2NoZW1hIiwKICAgICAgICAiY29uZGl0aW9ucyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIm9wZXJhdG9yIjogImVxdWFscyIsCiAgICAgICAgICAgICJwYXJhbWV0ZXJzIjogewogICAgICAgICAgICAgICJpbnB1dHMiOiBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICJhZGRyZXNzIjogIndhZi5jb250ZXh0LnByb2Nlc3NvciIsCiAgICAgICAgICAgICAgICAgICJrZXlfcGF0aCI6IFsKICAgICAgICAgICAgICAgICAgICAiZXh0cmFjdC1zY2hlbWEiCiAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAgICJ2YWx1ZSI6IHRydWUKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInBhcmFtZXRlcnMiOiB7CiAgICAgICAgICAibWFwcGluZ3MiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAiaW5wdXRzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAiYWRkcmVzcyI6ICJzZXJ2ZXIucmVxdWVzdC5xdWVyeSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICJvdXRwdXQiOiAiX2RkLmFwcHNlYy5zLnJlcS5xdWVyeXRlc3QiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAiaW5wdXRzIjogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAiYWRkcmVzcyI6ICJzZXJ2ZXIucmVxdWVzdC5ib2R5IgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgIm91dHB1dCI6ICJfZGQuYXBwc2VjLnMucmVxLmJvZHl0ZXN0IgogICAgICAgICAgICB9CiAgICAgICAgICBdLAogICAgICAgICAgInNjYW5uZXJzIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgInRhZ3MiOiB7CiAgICAgICAgICAgICAgICAiY2F0ZWdvcnkiOiAicGlpIgogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgXQogICAgICAgIH0sCiAgICAgICAgImV2YWx1YXRlIjogdHJ1ZSwKICAgICAgICAib3V0cHV0IjogdHJ1ZQogICAgICB9CiAgICBdLAogICAgInNjYW5uZXJzIjogW3sKICAgICAgImlkIjogInRlc3Qtc2Nhbm5lci0wMDEiLAogICAgICAibmFtZSI6ICJTdGFuZGFyZCBFLW1haWwgQWRkcmVzcyIsCiAgICAgICJrZXkiOiB7CiAgICAgICAgIm9wZXJhdG9yIjogIm1hdGNoX3JlZ2V4IiwKICAgICAgICAicGFyYW1ldGVycyI6IHsKICAgICAgICAgICJyZWdleCI6ICJcXGIoPzooPzplWy1cXHNdPyk/bWFpbHxhZGRyZXNzfHNlbmRlcnxcXGJ0b1xcYnxmcm9tfHJlY2lwaWVudClcXGIiLAogICAgICAgICAgIm9wdGlvbnMiOiB7CiAgICAgICAgICAgICJjYXNlX3NlbnNpdGl2ZSI6IGZhbHNlLAogICAgICAgICAgICAibWluX2xlbmd0aCI6IDIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0sCiAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAib3BlcmF0b3IiOiAibWF0Y2hfcmVnZXgiLAogICAgICAgICJwYXJhbWV0ZXJzIjogewogICAgICAgICAgInJlZ2V4IjogIlxcYltcXHchIyQlJicqKy89P2B7fH1+Xi1dKyg/OlxcLltcXHchIyQlJicqKy89P2B7fH1+Xi1dKykqKCU0MHxAKSg/OlthLXpBLVowLTktXStcXC4pK1thLXpBLVpdezIsNn1cXGIiLAogICAgICAgICAgIm9wdGlvbnMiOiB7CiAgICAgICAgICAgICJjYXNlX3NlbnNpdGl2ZSI6IGZhbHNlLAogICAgICAgICAgICAibWluX2xlbmd0aCI6IDUKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0sCiAgICAgICJ0YWdzIjogewogICAgICAgICJ0eXBlIjogImVtYWlsIiwKICAgICAgICAiY2F0ZWdvcnkiOiAicGlpIgogICAgICB9CiAgICB9XQogIH0KICAgIA==" - }, - { - "path": "datadog/2/ASM/ASM-base/config", - "raw": "ewogICJwcm9jZXNzb3Jfb3ZlcnJpZGUiOiBbCiAgICB7CiAgICAgICJ0YXJnZXQiOiBbImV4dHJhY3QtY29udGVudCJdLAogICAgICAic2Nhbm5lcnMiOiBbInRlc3Qtc2Nhbm5lci0wMDIiLCAidGVzdC1zY2FubmVyLWN1c3RvbS0wMDEiXQogICAgfQogIF0sCiAgImN1c3RvbV9zY2FubmVycyI6IFsKICAgIHsKICAgICAgICAiaWQiOiAidGVzdC1zY2FubmVyLWN1c3RvbS0wMDEiLAogICAgICAgICJuYW1lIjogIkN1c3RvbSBzY2FubmVyIiwKICAgICAgICAia2V5IjogewogICAgICAgICAgIm9wZXJhdG9yIjogIm1hdGNoX3JlZ2V4IiwKICAgICAgICAgICJwYXJhbWV0ZXJzIjogewogICAgICAgICAgICAicmVnZXgiOiAiXFxidGVzdGNhcmRcXGIiLAogICAgICAgICAgICAib3B0aW9ucyI6IHsKICAgICAgICAgICAgICAiY2FzZV9zZW5zaXRpdmUiOiBmYWxzZSwKICAgICAgICAgICAgICAibWluX2xlbmd0aCI6IDIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInZhbHVlIjogewogICAgICAgICAgIm9wZXJhdG9yIjogIm1hdGNoX3JlZ2V4IiwKICAgICAgICAgICJwYXJhbWV0ZXJzIjogewogICAgICAgICAgICAicmVnZXgiOiAiXFxiMTIzNDU2Nzg5MFxcYiIsCiAgICAgICAgICAgICJvcHRpb25zIjogewogICAgICAgICAgICAgICJjYXNlX3NlbnNpdGl2ZSI6IGZhbHNlLAogICAgICAgICAgICAgICJtaW5fbGVuZ3RoIjogNQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAidGFncyI6IHsKICAgICAgICAgICJ0eXBlIjogImNhcmQiLAogICAgICAgICAgImNhdGVnb3J5IjogInRlc3RjYXRlZ29yeSIKICAgICAgICB9CiAgICAgIH0KICBdCn0=" - } - ], - "client_configs": [ - "datadog/2/ASM/ASM-base/config", - "datadog/2/ASM_DD/ASM_DD-base/config", - "datadog/2/ASM_FEATURES/ASM_FEATURES-base/config" - ] - } -] diff --git a/utils/proxy/rc_mocked_responses_asm.json b/utils/proxy/rc_mocked_responses_asm.json deleted file mode 100644 index 796a8794d10..00000000000 --- a/utils/proxy/rc_mocked_responses_asm.json +++ /dev/null @@ -1,25 +0,0 @@ -[ - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvQVNNL0FTTS1iYXNlL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiIwZjU4YWFhMDFkYWRjMjQ3MWU2Mzk1YjliZDFkZjNmNThjOTY5YmI1ZjBhODIxNjM1YTQ4ZDdmZjU2YzkxNTJmIn0sImxlbmd0aCI6MjAxfSwiZGF0YWRvZy8yL0FTTS9BU00tc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJlMjhhYmUzNDIzYzBlZTJiN2E1MzFmNzIxN2UwZDI2OTA5YzAxMWRkYjU4OTc2OGUzYzkxMzM4OTlmNzBhZDdmIn0sImxlbmd0aCI6MTY5fX0sInZlcnNpb24iOjB9LCJzaWduYXR1cmVzIjpbeyJrZXlpZCI6ImVkNzY3MmM5YTI0YWJkYTc4ODcyZWUzMmVlNzFjN2NiMWQ1MjM1ZThkYjRlY2JmMWNhMjhiOWM1MGViNzVkOWUiLCJzaWciOiJmNWYyZjI3MDM1MzM5ZWQ4NDE0NDc3MTNlYjkzZTVjNjJjMzRmNGZhNzA5ZmFjMGY5ZWRjYTRlZjVkYzc3MzQwZTFlODFlNzc5YzViNTM2MzA0ZmU1NjgxNzNjOWMwZTkxMjViMTdjODRjZThhNThhOTA3YmIyZjI3ZTdkODkwYiJ9XX0=", - "target_files": [ - { - "path": "datadog/2/ASM/ASM-second/config", - "raw": "ewogICAgInJ1bGVzX292ZXJyaWRlIjogWwogICAgICAgIHsKICAgICAgICAgICAgInJ1bGVzX3RhcmdldCI6IFsKICAgICAgICAgICAgICAgIHsicnVsZV9pZCI6ICJjcnMtOTEzLTExMCJ9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJvbl9tYXRjaCI6IFtdCiAgICAgICAgfQogICAgXQp9Cg==" - }, - { - "path": "datadog/2/ASM/ASM-base/config", - "raw": "ewogICJydWxlc19vdmVycmlkZSI6IFsKICAgIHsKICAgICAgIm9uX21hdGNoIjogWwogICAgICAgICJibG9jayIKICAgICAgXSwKICAgICAgInJ1bGVzX3RhcmdldCI6IFsKICAgICAgICB7CiAgICAgICAgICAidGFncyI6IHsKICAgICAgICAgICAgImNvbmZpZGVuY2UiOiAiMSIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIF0KICAgIH0KICBdCn0K" - } - ], - "client_configs": [ - "datadog/2/ASM/ASM-base/config", - "datadog/2/ASM/ASM-second/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvQVNNL0FTTS1iYXNlL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiIwZjU4YWFhMDFkYWRjMjQ3MWU2Mzk1YjliZDFkZjNmNThjOTY5YmI1ZjBhODIxNjM1YTQ4ZDdmZjU2YzkxNTJmIn0sImxlbmd0aCI6MjAxfX0sInZlcnNpb24iOjF9LCJzaWduYXR1cmVzIjpbeyJrZXlpZCI6ImVkNzY3MmM5YTI0YWJkYTc4ODcyZWUzMmVlNzFjN2NiMWQ1MjM1ZThkYjRlY2JmMWNhMjhiOWM1MGViNzVkOWUiLCJzaWciOiJkNTkyMjU0NWVkMmNmZGU2N2I3MWJjMmY5N2U5ZmZmYzAxYjc1NzUyMGNiZGFjNzY1ZWM5ZjNhNDU2OTA1ZGNmOGQxY2NhODA3MWQwYjkwZjQ5ZWZiODY1OGE5YTA5MGQwODM3YWVhNTM5ZGNmMjZjMjAxMDZkYzE1YmI3MzEwYiJ9XX0=", - "client_configs": [ - "datadog/2/ASM/ASM-base/config" - ] - } -] \ No newline at end of file diff --git a/utils/proxy/rc_mocked_responses_asm_data.json b/utils/proxy/rc_mocked_responses_asm_data.json deleted file mode 100644 index 31941776348..00000000000 --- a/utils/proxy/rc_mocked_responses_asm_data.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjIwMjMtMDEtMTBUMDk6NTU6MjFaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6e30sInZlcnNpb24iOjF9LCJzaWduYXR1cmVzIjpbeyJrZXlpZCI6ImVkNzY3MmM5YTI0YWJkYTc4ODcyZWUzMmVlNzFjN2NiMWQ1MjM1ZThkYjRlY2JmMWNhMjhiOWM1MGViNzVkOWUiLCJzaWciOiIyNDBlNmZiY2NjYmYzZjQ2YmVhY2YyNTY3NmE0YTdjMGJlZDA5NThiZGZmODk0NjdjOGZjMzNmMDRjZTVhNWMyYTFjODUzOWM3MzY5MmZkNzEyN2E1YjdlYjcwNDJmODRmNDU2MGZkMmM1MzYyNjM5ZGNjY2FhY2IxMjk5ZjQwOCJ9XX0=" - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjIwMjMtMDEtMTBUMDk6NTU6MjFaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvQVNNX0RBVEEvQVNNX0RBVEEtYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiMjhlMDhmMjFjN2IyNjJmNzk1NzU3ZGEwMzYzYjI4ZmIyNWI1Zjk0Mzc2ZTVkNTRlNGJiYWI0NjEyMDg5YjhlYiJ9LCJsZW5ndGgiOjI3M319LCJ2ZXJzaW9uIjoyfSwic2lnbmF0dXJlcyI6W3sia2V5aWQiOiJlZDc2NzJjOWEyNGFiZGE3ODg3MmVlMzJlZTcxYzdjYjFkNTIzNWU4ZGI0ZWNiZjFjYTI4YjljNTBlYjc1ZDllIiwic2lnIjoiNGE5MmFhNDc5MDRkZmE4NTEwZjdlZDgwOGE5ZDMyOTUxMWJhZjZlYTgyODY3ZWRlMjE5NDliOWJmYzFjNWNlZWIxNzJhNWY2NTBiY2E5NzA3ZjM3ZDRhMzcwZmM1ODQ5NGVkMTJjYjBhYjgyOThlZjI5ZDE5YzliY2MzMGM5MDQifV19", - "target_files": [ - { - "path": "datadog/2/ASM_DATA/ASM_DATA-base/config", - "raw": "ewogICJydWxlc19kYXRhIjogWwogICAgewogICAgICAiaWQiOiAiYmxvY2tlZF9pcHMiLAogICAgICAidHlwZSI6ICJpcF93aXRoX2V4cGlyYXRpb24iLAogICAgICAiZGF0YSI6IFsKICAgICAgICB7ICJ2YWx1ZSI6ICI0Mi40Mi40Mi4xIiwgImV4cGlyYXRpb24iOiAzNjU3NTI5NzQzIH0sCiAgICAgICAgeyAidmFsdWUiOiAiNDIuNDIuNDIuMiIgfSwKICAgICAgICB7ICJ2YWx1ZSI6ICI0Mi40Mi40Mi4zIiwgImV4cGlyYXRpb24iOiAxMiB9CiAgICAgIF0KICAgIH0KICBdCn0K" - } - ], - "client_configs": [ - "datadog/2/ASM_DATA/ASM_DATA-base/config" - ] - } -] diff --git a/utils/proxy/rc_mocked_responses_asm_data_full_denylist.json b/utils/proxy/rc_mocked_responses_asm_data_full_denylist.json deleted file mode 100644 index 5b881558dfa..00000000000 --- a/utils/proxy/rc_mocked_responses_asm_data_full_denylist.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6e30sInZlcnNpb24iOjF9LCJzaWduYXR1cmVzIjpbeyJrZXlpZCI6ImVkNzY3MmM5YTI0YWJkYTc4ODcyZWUzMmVlNzFjN2NiMWQ1MjM1ZThkYjRlY2JmMWNhMjhiOWM1MGViNzVkOWUiLCJzaWciOiJlMjI3OWE1NTRkNTI1MDNmNWJkNjhlMGE5OTEwYzdlOTBjOWJiODE3NDRmZTljODgyNGVhMzczN2IyNzlkOWU2OWIzY2U1ZjRiNDYzYzQwMmViZTM0OTY0ZmI3YTY5NjI1ZWIwZTkxZDNkZGJkMzkyY2M4YjMyMTAzNzNkOWIwZiJ9XX0=" - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvQVNNX0RBVEEvQVNNX0RBVEEtYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiNTdjMWZiZjc2ODViMDU5MjZiMTdlNzYxYWMxM2MzMDY0ZTc4YmQzMDNmYTU0YmM1ZGY1OThiNDljZmFiMDFkZCJ9LCJsZW5ndGgiOjEzMTkzNjZ9fSwidmVyc2lvbiI6Mn0sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6IjE1YjQ4YTMyMTUzOTQ1MzI5ZDFjMzFlOGQ4MDQxZjU1ZDUwYzRkNzY0NmI1MTZlOTJhZDkxZjJjY2Q2YjMyZjYxMGNiZjM4NzRkMGE3ODY1MDgxOThjNDA2ZWMxNjVjNzA2ZTBhMDUyMjdiNjkzYjliYzEwOTk3YzVlOWJjNzA2In1dfQ==", - "target_files": [ - { - "path": "datadog/2/ASM_DATA/ASM_DATA-base/config", - "raw": "ewogICJydWxlc19kYXRhIjogWwogICAgewogICAgICAiaWQiOiAiYmxvY2tlZF9pcHMiLAogICAgICAidHlwZSI6ICJpcF93aXRoX2V4cGlyYXRpb24iLAogICAgICAiZGF0YSI6IFsKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjAuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMC4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4wLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMS4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xLjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yLjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMi4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMy4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNC4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNS4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNi4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNy4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjguMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOC4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOS4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEwLjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTAuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMC4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMS45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjExLjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTEuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTIuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMi45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEyLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjEzLjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTMuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xMy4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNC45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE0Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTQuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTUuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNS45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE1LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE2Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTYuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNi4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xNy45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE3Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTcuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTguOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOC45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE4LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjE5Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMTkuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4xOS4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMC45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIwLjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjAuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjEuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMS45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIxLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIyLjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjIuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMi4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yMy45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjIzLjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjMuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjQuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNC45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI0LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI1Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjUuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNS4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNi45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI2Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjYuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjcuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yNy45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI3LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI4Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjguOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOC4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4yOS45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjI5Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMjkuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzAuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMC45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMwLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMxLjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzEuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMS4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMi45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMyLjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzIuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzMuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zMy45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjMzLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM0Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzQuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNC4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNS45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM1Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzUuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzYuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNi45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM2LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM3Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzcuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zNy4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOC45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM4Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzguMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguMzkuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC4zOS45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjM5LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQwLjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDAuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MC4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40MS45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQxLjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDEuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDIuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Mi45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQyLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQzLjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDMuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40My4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NC45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ0Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDQuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDUuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40NS45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ1LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ2Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDYuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ni4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40Ny45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ3Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDcuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDguOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OC45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ4LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjQ5Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNDkuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC40OS4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MC45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUwLjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTAuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTEuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41MS45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUxLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUyLjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTIuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Mi4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41My45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjUzLjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTMuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTQuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NC45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU0LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU1Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTUuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41NS4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ni45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU2Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTYuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTcuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41Ny45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU3LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU4Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTguOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OC4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC41OS45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjU5Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNTkuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjAuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MC45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYwLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYxLjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjEuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42MS4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Mi45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYyLjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjIuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjMuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42My45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjYzLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY0Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjQuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NC4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42NS45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY1Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjUuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjYuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ni45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY2LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY3Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjcuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42Ny4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OC45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY4Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjguMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNjkuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC42OS45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjY5LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcwLjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzAuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MC4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43MS45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcxLjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzEuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzIuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Mi45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjcyLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjczLjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzMuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43My4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NC45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc0Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzQuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzUuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43NS45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc1LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc2Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzYuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ni4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43Ny45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc3Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzcuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzguOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OC45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc4LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljc5Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguNzkuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC43OS4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MC45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgwLjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODAuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODEuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44MS45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgxLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgyLjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODIuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Mi4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44My45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjgzLjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODMuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODQuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NC45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg0LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg1Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODUuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44NS4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ni45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg2Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODYuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODcuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44Ny45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg3LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg4Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODguOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OC4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC44OS45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljg5Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguODkuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTAuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MC45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkwLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkxLjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTEuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45MS4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Mi45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkyLjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTIuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTMuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45My45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44LjkzLjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk0Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTQuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NC4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45NS45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk1Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTUuMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTYuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ni45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk2LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny40IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny43IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4yMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4yNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4yOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4zMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4zNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4zNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny40MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny40MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny40NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny40OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny41MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny41NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny41OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny42MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny42NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny42NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny43MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny43MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3Ljc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny43NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3Ljc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny43OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny44MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny44NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3Ljg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny44OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3Ljg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny45MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3LjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny45NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3Ljk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny45NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk3Ljk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTcuOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45Ny4xMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC4wIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC4zIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC42IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC45IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC4xMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC4xNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC4xNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC4yMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC4yMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC4yNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC4yOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC4zMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC4zNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC4zOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC40MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC40NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC40NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC41MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC41MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC41NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC41OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC42MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC42NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC42OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC43MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC43NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4Ljc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC43NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4Ljc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC44MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC44MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4Ljg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC44NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4Ljg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC44OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC45MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4LjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC45NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4Ljk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OC45OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk4Ljk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTguMTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS4yIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS41IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS44IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS4xMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS4xNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS4xOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS4yMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS4yNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS4yNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS4zMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS4zMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS4zNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS4zOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS40MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS40NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS40OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS41MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS41NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS41NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS42MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS42MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS42NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS42OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS43MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS43NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5Ljc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS43OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5Ljc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS44MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS44NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5Ljg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS44NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5Ljg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS45MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS45MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5Ljk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS45NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5Ljk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyLjguOTkuOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIuOC45OS45OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMi44Ljk5LjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9CiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJpZCI6ICJibG9ja2VkX3VzZXJzIiwKICAgICAgInR5cGUiOiAiZGF0YV93aXRoX2V4cGlyYXRpb24iLAogICAgICAiZGF0YSI6IFsKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI1MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI1NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI1OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI2MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI2NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI2NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI3MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI3MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI3NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI3OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI4MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI4NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI4OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI5MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI5NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI5NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMxMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMxNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMxOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMyNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMzMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMzMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMzNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjMzOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM0MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM0NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM0OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM1MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM1NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM1NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM2MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM2MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM2NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM2OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM3MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM3NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM3OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM4MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM4NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM4NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM5MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM5MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM5NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIzOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMzk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjM5OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQxMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQxNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQxNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQyNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQyOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQzMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQzNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQzOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0MzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ0MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ0NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ0NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ1MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ1MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ1NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ1OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ2MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ2NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ2OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ3MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ3NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ3NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0NzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ4MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0ODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ4MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0ODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ4NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0ODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ4OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0OTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ5MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0OTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ5NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0OTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNDk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjQ5OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI0OTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUxMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUxMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUxNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUxOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUyNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUyOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUzMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUzNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjUzNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1MzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU0MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU0MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU0NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU0OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU1MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU1NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU1OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU2MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU2NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU2NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU3MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU3MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU3NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1NzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU3OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1ODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU4MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1ODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU4NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1ODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU4OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1ODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU5MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1OTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU5NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1OTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjU5NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI1OTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNTk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYxMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYxNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYxOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYyNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYzMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYzMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYzNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2MzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjYzOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY0MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY0NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY0OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY1MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY1NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY1NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY2MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY2MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY2NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY2OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY3MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY3NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY3OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2NzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY4MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2ODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY4NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2ODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY4NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2ODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY5MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2OTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY5MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2OTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY5NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI2OTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNjk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjY5OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjcwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjcwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjcwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjcxMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjcxNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjcxNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjcyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjcyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjcyNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjcyOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjczMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjczNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjczOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3MzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc0MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc0NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc0NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc1MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc1MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc1NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc1OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc2MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc2NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc2OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc3MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc3NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc3NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3NzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc4MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3ODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc4MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3ODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc4NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3ODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc4OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3OTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc5MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3OTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc5NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3OTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiNzk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjc5OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI3OTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgxMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgxMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgxNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgxOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgyNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgyOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgzMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgzNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjgzNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4MzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg0MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg0MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg0NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg0OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg1MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg1NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg1OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg2MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg2NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg2NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg3MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg3MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg3NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4NzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg3OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4ODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg4MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4ODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg4NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4ODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg4OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4ODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg5MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4OTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg5NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4OTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjg5NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI4OTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiODk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkxMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkxNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkxOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkyNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkzMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkzMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkzNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5MzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjkzOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk0MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk0NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk0OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk1MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk1NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk1NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk2MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk2MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk2NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk2OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk3MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk3NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk3OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5NzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk4MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5ODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk4NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5ODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk4NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5ODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk5MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5OTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk5MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5OTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk5NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICI5OTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiOTk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjk5OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAxMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAxNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAxNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAyNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAyOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAzMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAzNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTAzOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA0MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA0NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA0NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA1MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA1MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA1NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA1OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA2MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA2NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA2OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA3MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA3NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA3NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA4MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA4MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA4NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA4OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA5MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA5NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEwOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTA5OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMDk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTEwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTEwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTEwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTExMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTExMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTExNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTExOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTEyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTEyNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTEyOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTEzMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTEzNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTEzNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE0MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE0MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE0NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE0OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE1MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE1NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE1OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE2MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE2NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE2NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE3MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE3MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE3NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE3OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE4MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE4NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE4OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE5MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE5NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTE5NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMTk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjExOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIxMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIxNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIxOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIyNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIzMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIzMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIzNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTIzOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI0MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI0NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI0OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI1MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI1NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI1NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI2MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI2MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI2NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI2OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI3MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI3NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI3OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI4MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI4NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI4NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI5MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI5MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI5NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMjk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEyOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTI5OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMxMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMxNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMxNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMyNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMyOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMzMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMzNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTMzOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM0MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM0NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM0NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM1MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM1MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM1NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM1OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM2MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM2NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM2OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM3MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM3NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM3NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM4MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM4MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM4NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM4OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM5MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM5NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjEzOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTM5OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxMzk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQxMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQxMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQxNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQxOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQyNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQyOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQzMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQzNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQzNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0MzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ0MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ0MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ0NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ0OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ1MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ1NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ1OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ2MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ2NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ2NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ3MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ3MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ3NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0NzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ3OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0ODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ4MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0ODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ4NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0ODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ4OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0OTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ5MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0OTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ5NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0OTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTQ5NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNDk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE0OTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUxMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUxNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUxOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUyNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUzMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUzMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUzNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1MzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTUzOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU0MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU0NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU0OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU1MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU1NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU1NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU2MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU2MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU2NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU2OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU3MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU3NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1NzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU3OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1ODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU4MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1ODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU4NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1ODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU4NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1ODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU5MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1OTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU5MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1OTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU5NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNTk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE1OTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTU5OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYxMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYxNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYxNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYyNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYyOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYzMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYzNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2MzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTYzOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY0MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY0NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY0NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY1MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY1MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY1NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY1OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY2MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY2NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY2OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY3MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY3NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY3NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2NzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY4MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2ODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY4MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2ODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY4NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2ODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY4OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2OTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY5MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2OTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY5NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE2OTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTY5OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTcwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTcwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTcwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTcxMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTcxMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTcxNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTcxOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTcyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTcyNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTcyOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTczMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTczNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTczNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3MzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc0MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc0MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc0NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc0OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc1MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc1NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc1OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc2MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc2NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc2NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc3MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc3MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc3NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3NzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc3OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3ODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc4MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3ODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc4NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3ODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc4OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3OTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc5MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3OTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc5NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3OTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTc5NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxNzk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE3OTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgxMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgxNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgxOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgyNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgzMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgzMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgzNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4MzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTgzOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg0MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg0NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg0OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg1MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg1NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg1NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg2MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg2MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg2NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg2OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg3MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg3NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4NzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg3OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4ODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg4MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4ODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg4NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4ODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg4NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4ODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg5MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4OTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg5MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4OTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg5NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxODk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE4OTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTg5OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkxMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkxNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkxNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkyNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkyOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkzMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkzNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5MzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTkzOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk0MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk0NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk0NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk1MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk1MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk1NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk1OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk2MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk2NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk2OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk3MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk3NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk3NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5NzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk4MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5ODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk4MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5ODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk4NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5ODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk4OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5OTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk5MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5OTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk5NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjE5OTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMTk5OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIxOTk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAxMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAxMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAxNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAxOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAyNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAyOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAzMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAzNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjAzNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA0MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA0MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA0NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA0OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA1MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA1NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA1OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA2MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA2NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA2NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA3MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA3MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA3NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA3OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA4MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA4NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA4OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA5MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA5NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjA5NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMDk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIwOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjEwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjEwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjEwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjEwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjExMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjExNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjExOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjEyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjEyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjEyNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjEzMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjEzMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjEzNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxMzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjEzOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE0MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE0NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE0OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE1MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE1NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE1NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE2MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE2MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE2NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE2OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE3MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE3NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxNzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE3OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE4MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE4NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE4NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE5MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxOTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE5MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxOTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE5NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMTk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIxOTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjE5OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjAwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIwMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjAzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIwNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjA2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIwOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjA5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIxMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjEyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIxNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjE1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIxNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjE4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIyMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjIxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIyMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjI0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIyNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjI3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIyOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjMwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIzMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjMzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIzNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjM2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyMzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjIzOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjM5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI0MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjQyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI0NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjQ1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI0NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjQ4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI1MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjUxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI1MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjU0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI1NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjU3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI1OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjYwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI2MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjYzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI2NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjY2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI2OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjY5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI3MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjcyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI3NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjc1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI3NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjc4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyNzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI4MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjgxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyODIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI4MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjg0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyODUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI4NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjg3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyODgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI4OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjkwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyOTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI5MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjkzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyOTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI5NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjk2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIyOTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjI5OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMjk5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMDAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMwMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzAyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMDMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMwNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzA1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMDYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMwNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzA4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMDkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMxMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzExIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMxMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzE0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMxNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzE3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMxOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzIwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMjEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMyMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzIzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMjQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMyNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzI2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMjciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMyOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzI5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMzAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMzMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzMyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMzMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMzNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzM1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMzYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjMzNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzM4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzMzkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM0MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzQxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM0MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzQ0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM0NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzQ3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM0OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzUwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM1MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzUzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM1NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzU2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM1OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzU5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM2MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzYyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM2NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzY1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM2NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzY4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM3MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzcxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM3MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzc0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM3NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzc3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzNzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM3OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzgwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzODEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM4MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzgzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzODQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM4NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzg2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzODciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM4OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzg5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzOTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM5MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzkyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzOTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM5NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzk1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzOTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjM5NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyMzk4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjIzOTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQwMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDAxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MDIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQwMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDA0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MDUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQwNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDA3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MDgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQwOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDEwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MTEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQxMiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDEzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MTQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQxNSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDE2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MTciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQxOCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDE5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MjAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQyMSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDIyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MjMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQyNCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDI1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MjYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQyNyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDI4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MjkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQzMCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDMxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MzIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQzMyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDM0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MzUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQzNiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDM3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0MzgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQzOSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDQwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NDEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ0MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDQzIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NDQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ0NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDQ2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NDciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ0OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDQ5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NTAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ1MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDUyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NTMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ1NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDU1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NTYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ1NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDU4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NTkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ2MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDYxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NjIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ2MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDY0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NjUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ2NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDY3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NjgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ2OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDcwIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NzEiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ3MiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDczIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NzQiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ3NSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDc2IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0NzciLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ3OCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDc5IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0ODAiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ4MSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDgyIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0ODMiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ4NCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDg1IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0ODYiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ4NyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDg4IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0ODkiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ5MCIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDkxIiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0OTIiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ5MyIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDk0IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0OTUiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ5NiIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJ2YWx1ZSI6ICIyNDk3IiwKICAgICAgICAgICJleHBpcmF0aW9uIjogOTk5OTk5OTk5OQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgInZhbHVlIjogIjI0OTgiLAogICAgICAgICAgImV4cGlyYXRpb24iOiA5OTk5OTk5OTk5CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAidmFsdWUiOiAiMjQ5OSIsCiAgICAgICAgICAiZXhwaXJhdGlvbiI6IDk5OTk5OTk5OTkKICAgICAgICB9CiAgICAgIF0KICAgIH0KICBdCn0=" - } - ], - "client_configs": [ - "datadog/2/ASM_DATA/ASM_DATA-base/config" - ] - } -] \ No newline at end of file diff --git a/utils/proxy/rc_mocked_responses_asm_nocache.json b/utils/proxy/rc_mocked_responses_asm_nocache.json deleted file mode 100644 index f146ac4e551..00000000000 --- a/utils/proxy/rc_mocked_responses_asm_nocache.json +++ /dev/null @@ -1,31 +0,0 @@ -[ - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvQVNNL0FTTS1iYXNlL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJkZDZiNjRjZjk4MzIzZDRmYTZjNWM3MDAxM2E3ZjQ3MGQ0MjVlNDA4ZDgyNjQ5N2Q2NjU5Mzg5NzU4Nzc4MWE0In0sImxlbmd0aCI6MTc5fSwiZGF0YWRvZy8yL0FTTS9BU00tc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJlMjhhYmUzNDIzYzBlZTJiN2E1MzFmNzIxN2UwZDI2OTA5YzAxMWRkYjU4OTc2OGUzYzkxMzM4OTlmNzBhZDdmIn0sImxlbmd0aCI6MTY5fX0sInZlcnNpb24iOjB9LCJzaWduYXR1cmVzIjpbeyJrZXlpZCI6ImVkNzY3MmM5YTI0YWJkYTc4ODcyZWUzMmVlNzFjN2NiMWQ1MjM1ZThkYjRlY2JmMWNhMjhiOWM1MGViNzVkOWUiLCJzaWciOiJjNmYzYjc3N2JlNjIwYTZiZGYxMDRlZWQ0NjVhMzZhMzE3NzcyYmY1ZWVjYTVkYjdiNDRjNzIyYjA3ZWRjYjcyZmNmODhiNWM4OTk0YTQ0NWIzODk1MDQ0OTQ2YTI0ZGRjMTYxZjk2NGM4YjFkMzExNDg5YThlODg1ODM4NjQwMyJ9XX0=", - "target_files": [ - { - "path": "datadog/2/ASM/ASM-second/config", - "raw": "ewogICAgInJ1bGVzX292ZXJyaWRlIjogWwogICAgICAgIHsKICAgICAgICAgICAgInJ1bGVzX3RhcmdldCI6IFsKICAgICAgICAgICAgICAgIHsicnVsZV9pZCI6ICJjcnMtOTEzLTExMCJ9CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJvbl9tYXRjaCI6IFtdCiAgICAgICAgfQogICAgXQp9Cg==" - }, - { - "path": "datadog/2/ASM/ASM-base/config", - "raw": "ewogICAgInJ1bGVzX292ZXJyaWRlIjogWwogICAgICAgIHsKICAgICAgICAgICAgInJ1bGVzX3RhcmdldCI6IFsKICAgICAgICAgICAgICAgIHsidGFncyI6IHsiY29uZmlkZW5jZSI6ICIxIn19CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJvbl9tYXRjaCI6IFsiYmxvY2siXQogICAgICAgIH0KICAgIF0KfQo=" - } - ], - "client_configs": [ - "datadog/2/ASM/ASM-base/config", - "datadog/2/ASM/ASM-second/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvQVNNL0FTTS1iYXNlL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJkZDZiNjRjZjk4MzIzZDRmYTZjNWM3MDAxM2E3ZjQ3MGQ0MjVlNDA4ZDgyNjQ5N2Q2NjU5Mzg5NzU4Nzc4MWE0In0sImxlbmd0aCI6MTc5fX0sInZlcnNpb24iOjF9LCJzaWduYXR1cmVzIjpbeyJrZXlpZCI6ImVkNzY3MmM5YTI0YWJkYTc4ODcyZWUzMmVlNzFjN2NiMWQ1MjM1ZThkYjRlY2JmMWNhMjhiOWM1MGViNzVkOWUiLCJzaWciOiI0MzA2OTY3OTgwNDY4ZWEzOWZmZDc0NWYwMzQ5YWIzMjkyMmU1NzU0OGVkMmM3Y2E1OTFjNmZkY2JmMTFlMDNiNzY3MzBkNzI3MmJmNThmODM5ZDY2ODJhOWFlMGRmYjM3MDYzMDA5MGRhM2MzYmUzNDM4ZGYwNGFhMTgzMTQwZSJ9XX0=", - "target_files": [ - { - "path": "datadog/2/ASM/ASM-base/config", - "raw": "ewogICAgInJ1bGVzX292ZXJyaWRlIjogWwogICAgICAgIHsKICAgICAgICAgICAgInJ1bGVzX3RhcmdldCI6IFsKICAgICAgICAgICAgICAgIHsidGFncyI6IHsiY29uZmlkZW5jZSI6ICIxIn19CiAgICAgICAgICAgIF0sCiAgICAgICAgICAgICJvbl9tYXRjaCI6IFsiYmxvY2siXQogICAgICAgIH0KICAgIF0KfQo=" - } - ], - "client_configs": [ - "datadog/2/ASM/ASM-base/config" - ] - } -] \ No newline at end of file diff --git a/utils/proxy/rc_mocked_responses_debugger_expression_language.json b/utils/proxy/rc_mocked_responses_debugger_expression_language.json deleted file mode 100644 index 7eac5ad2cef..00000000000 --- a/utils/proxy/rc_mocked_responses_debugger_expression_language.json +++ /dev/null @@ -1,276 +0,0 @@ -[ - null, - [ - { - "language": "", - "id": "log170aa-expr-lang-0001-1478a6method", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "Expression", - "sourceFile": null - }, - "evaluateAt": "EXIT", - "segments": [ - { - "str": "Accessing input variable. Value is: " - }, - { - "dsl": "", - "json": { - "ref": "inputValue" - } - } - ] - }, - { - "language": "", - "id": "log170aa-expr-lang-0002-1478a6method", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "Expression", - "sourceFile": null - }, - "evaluateAt": "EXIT", - "segments": [ - { - "str": "Accessing return variable. Value is: " - }, - { - "dsl": "", - "json": { - "ref": "@return" - } - } - ] - }, - { - "language": "", - "id": "log170aa-expr-lang-0003-1478a6method", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "Expression", - "sourceFile": null - }, - "evaluateAt": "EXIT", - "segments": [ - { - "str": "Accessing local variable. Value is: " - }, - { - "dsl": "", - "json": { - "ref": "localValue" - } - } - ] - }, - { - "language": "", - "id": "log170aa-expr-lang-0004-1478a6method", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "Expression", - "sourceFile": null - }, - "evaluateAt": "EXIT", - "segments": [ - { - "str": "Accessing complex object int variable. Value is: " - }, - { - "dsl": "", - "json": { - "getmember": [ - { - "ref": "testStruct" - }, - "IntValue" - ] - } - } - ] - }, - { - "language": "", - "id": "log170aa-expr-lang-0005-1478a6method", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "Expression", - "sourceFile": null - }, - "evaluateAt": "EXIT", - "segments": [ - { - "str": "Accessing complex object double variable. Value is: " - }, - { - "dsl": "", - "json": { - "getmember": [ - { - "ref": "testStruct" - }, - "DoubleValue" - ] - } - } - ] - }, - { - "language": "", - "id": "log170aa-expr-lang-0006-1478a6method", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "Expression", - "sourceFile": null - }, - "evaluateAt": "EXIT", - "segments": [ - { - "str": "Accessing complex object string variable. Value is: " - }, - { - "dsl": "", - "json": { - "getmember": [ - { - "ref": "testStruct" - }, - "StringValue" - ] - } - } - ] - }, - { - "language": "", - "id": "log170aa-expr-lang-0007-1478a6method", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "Expression", - "sourceFile": null - }, - "evaluateAt": "EXIT", - "segments": [ - { - "str": "Accessing complex object bool variable. Value is: " - }, - { - "dsl": "", - "json": { - "getmember": [ - { - "ref": "testStruct" - }, - "BoolValue" - ] - } - } - ] - }, - { - "language": "", - "id": "log170aa-expr-lang-0008-1478a6method", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "Expression", - "sourceFile": null - }, - "evaluateAt": "EXIT", - "segments": [ - { - "str": "Accessing complex object collection first variable. Value is: " - }, - { - "dsl": "", - "json": { - "index": [ - { - "getmember": [ - { - "ref": "testStruct" - }, - "Collection" - ] - }, - 0 - ] - } - } - ] - }, - { - "language": "", - "id": "log170aa-expr-lang-0009-1478a6method", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "Expression", - "sourceFile": null - }, - "evaluateAt": "EXIT", - "segments": [ - { - "str": "Accessing complex object dictionary 'two' keyword. Value is: " - }, - { - "dsl": "", - "json": { - "index": [ - { - "getmember": [ - { - "ref": "testStruct" - }, - "Dictionary" - ] - }, - "two" - ] - } - } - ] - }, - { - "language": "", - "id": "log170aa-expr-lang-0010-1478a6method", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "Expression", - "sourceFile": null - }, - "evaluateAt": "EXIT", - "segments": [ - { - "str": "Accessing duration variable. Value is: " - }, - { - "dsl": "", - "json": { - "ref": "@duration" - } - } - ] - }, - { - "language": "", - "id": "log170aa-expr-lang-0011-1478a6method", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "ExpressionException", - "sourceFile": null - }, - "evaluateAt": "EXIT", - "segments": [ - { - "str": "Accessing exception variable. Value is: " - }, - { - "dsl": "", - "json": { - "ref": "@exception" - } - } - ] - } - ] -] \ No newline at end of file diff --git a/utils/proxy/rc_mocked_responses_debugger_line_probes_snapshot.json b/utils/proxy/rc_mocked_responses_debugger_line_probes_snapshot.json deleted file mode 100644 index e7e08bed5f4..00000000000 --- a/utils/proxy/rc_mocked_responses_debugger_line_probes_snapshot.json +++ /dev/null @@ -1,79 +0,0 @@ -[ - null, - [ - { - "language": "", - "id": "log170aa-acda-4453-9111-1478a697line", - "where": { - "typeName": null, - "sourceFile": "ACTUAL_SOURCE_FILE", - "lines": [ - "20" - ] - } - }, - { - "language": "", - "id": "metricaa-acda-4453-9111-1478a697line", - "kind": "COUNT", - "metricName": "MetricCountInt", - "value": { - "json": { - "ref": "id" - } - }, - "where": { - "typeName": null, - "sourceFile": "ACTUAL_SOURCE_FILE", - "lines": [ - "28" - ] - }, - "evaluateAt": "EXIT" - }, - { - "language": "", - "id": "decor0aa-acda-4453-9111-1478a697line", - "targetSpan": "ACTIVE", - "decorations": [ - { - "when": { - "json": { - "gt": [ - { - "ref": "intLocal" - }, - { - "ref": "intArg" - } - ] - } - }, - "tags": [ - { - "name": "SpanDecorationArgsAndLocals", - "value": { - "template": null, - "segments": [ - { - "json": { - "ref": "intLocal" - } - } - ] - } - } - ] - } - ], - "where": { - "typeName": null, - "sourceFile": "ACTUAL_SOURCE_FILE", - "lines": [ - "44" - ] - }, - "evaluateAt": "EXIT" - } - ] -] \ No newline at end of file diff --git a/utils/proxy/rc_mocked_responses_debugger_method_probes_snapshot.json b/utils/proxy/rc_mocked_responses_debugger_method_probes_snapshot.json deleted file mode 100644 index 6feb3379844..00000000000 --- a/utils/proxy/rc_mocked_responses_debugger_method_probes_snapshot.json +++ /dev/null @@ -1,84 +0,0 @@ -[ - null, - [ - { - "language": "", - "id": "log170aa-acda-4453-9111-1478a6method", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "LogProbe", - "sourceFile": null - }, - "evaluateAt": "EXIT" - }, - { - "language": "", - "id": "metricaa-acda-4453-9111-1478a6method", - "metricName": "MetricCountInt", - "kind": "COUNT", - "value": { - "json": { - "ref": "id" - } - }, - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "MetricProbe", - "sourceFile": null - }, - "evaluateAt": "EXIT" - }, - { - "language": "", - "id": "span70aa-acda-4453-9111-1478a6method", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "SpanProbe", - "sourceFile": null - }, - "evaluateAt": "EXIT" - }, - { - "language": "", - "id": "decor0aa-acda-4453-9111-1478a6method", - "targetSpan": "ACTIVE", - "decorations": [ - { - "when": { - "json": { - "gt": [ - { - "ref": "intLocal" - }, - { - "ref": "intArg" - } - ] - } - }, - "tags": [ - { - "name": "SpanDecorationArgsAndLocals", - "value": { - "template": null, - "segments": [ - { - "json": { - "ref": "intLocal" - } - } - ] - } - } - ] - } - ], - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "SpanDecorationProbe", - "sourceFile": null - }, - "evaluateAt": "EXIT" - } - ] -] \ No newline at end of file diff --git a/utils/proxy/rc_mocked_responses_debugger_mix_log_probe.json b/utils/proxy/rc_mocked_responses_debugger_mix_log_probe.json deleted file mode 100644 index 1d3810eeac3..00000000000 --- a/utils/proxy/rc_mocked_responses_debugger_mix_log_probe.json +++ /dev/null @@ -1,28 +0,0 @@ -[ - null, - [ - { - "language": "", - "id": "logfb5a-1974-4cdb-b1dd-77dba2method", - "captureSnapshot": true, - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "MixProbe", - "sourceFile": null - }, - "evaluateAt": "EXIT" - }, - { - "language": "", - "id": "logfb5a-1974-4cdb-b1dd-77dba2f1line", - "captureSnapshot": true, - "where": { - "typeName": null, - "sourceFile": "ACTUAL_SOURCE_FILE", - "lines": [ - "52" - ] - } - } - ] -] \ No newline at end of file diff --git a/utils/proxy/rc_mocked_responses_debugger_probes_status.json b/utils/proxy/rc_mocked_responses_debugger_probes_status.json deleted file mode 100644 index f504e9d4c6d..00000000000 --- a/utils/proxy/rc_mocked_responses_debugger_probes_status.json +++ /dev/null @@ -1,198 +0,0 @@ -[ - null, - [ - { - "language": "", - "id": "loga0cf2-meth-45cf-9f39-591received", - "where": { - "typeName": "NotReallyExists", - "methodName": "SomeMethod", - "sourceFile": null - }, - "evaluateAt": "EXIT" - }, - { - "language": "", - "id": "loga0cf2-meth-45cf-9f39-59installed", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "LogProbe", - "sourceFile": null - }, - "evaluateAt": "EXIT" - }, - { - "language": "", - "id": "loga0cf2-line-45cf-9f39-59installed", - "where": { - "typeName": null, - "sourceFile": "ACTUAL_SOURCE_FILE", - "lines": [ - "20" - ] - } - } - ], - [ - { - "language": "", - "id": "metricf2-meth-45cf-9f39-591received", - "metricName": "MetricCountInt", - "kind": "COUNT", - "value": { - "json": { - "ref": "id" - } - }, - "where": { - "typeName": "NotReallyExists", - "methodName": "SomeMethod", - "sourceFile": null - }, - "evaluateAt": "EXIT" - }, - { - "language": "", - "id": "metricf2-meth-45cf-9f39-59installed", - "metricName": "MetricCountInt", - "kind": "COUNT", - "value": { - "json": { - "ref": "id" - } - }, - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "MetricProbe", - "sourceFile": null - }, - "evaluateAt": "EXIT" - }, - { - "language": "", - "id": "metricf2-line-45cf-9f39-59installed", - "kind": "COUNT", - "metricName": "MetricCountInt", - "value": { - "json": { - "ref": "id" - } - }, - "where": { - "typeName": null, - "sourceFile": "ACTUAL_SOURCE_FILE", - "lines": [ - "28" - ] - }, - "evaluateAt": "EXIT" - } - ], - [ - { - "language": "", - "id": "span0cf2-meth-45cf-9f39-591received", - "where": { - "typeName": "NotReallyExists", - "methodName": "SomeMethod", - "sourceFile": null - }, - "evaluateAt": "EXIT" - }, - { - "language": "", - "id": "span0cf2-meth-45cf-9f39-59installed", - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "SpanProbe", - "sourceFile": null - }, - "evaluateAt": "EXIT" - } - ], - [ - { - "language": "", - "id": "decorcf2-meth-45cf-9f39-591received", - "targetSpan": "ACTIVE", - "decorations": [ - { - "when": { - "json": { - "gt": [ - { - "ref": "intLocal" - }, - { - "ref": "intArg" - } - ] - } - } - } - ], - "where": { - "typeName": "NotReallyExists", - "methodName": "SomeMethod", - "sourceFile": null - }, - "evaluateAt": "EXIT" - }, - { - "language": "", - "id": "decorcf2-meth-45cf-9f39-59installed", - "targetSpan": "ACTIVE", - "decorations": [ - { - "when": { - "json": { - "gt": [ - { - "ref": "intLocal" - }, - { - "ref": "intArg" - } - ] - } - } - } - ], - "where": { - "typeName": "ACTUAL_TYPE_NAME", - "methodName": "SpanDecorationProbe", - "sourceFile": null - }, - "evaluateAt": "EXIT" - }, - { - "language": "", - "id": "decorcf2-line-45cf-9f39-59installed", - "targetSpan": "ACTIVE", - "decorations": [ - { - "when": { - "json": { - "gt": [ - { - "ref": "intLocal" - }, - { - "ref": "intArg" - } - ] - } - } - } - ], - "where": { - "typeName": null, - "sourceFile": "ACTUAL_SOURCE_FILE", - "lines": [ - "44" - ] - }, - "evaluateAt": "EXIT" - } - ] -] \ No newline at end of file diff --git a/utils/proxy/rc_mocked_responses_live_debugging.json b/utils/proxy/rc_mocked_responses_live_debugging.json deleted file mode 100644 index cb77657dba7..00000000000 --- a/utils/proxy/rc_mocked_responses_live_debugging.json +++ /dev/null @@ -1,157 +0,0 @@ -[ - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6e30sInZlcnNpb24iOjF9LCJzaWduYXR1cmVzIjpbeyJrZXlpZCI6ImVkNzY3MmM5YTI0YWJkYTc4ODcyZWUzMmVlNzFjN2NiMWQ1MjM1ZThkYjRlY2JmMWNhMjhiOWM1MGViNzVkOWUiLCJzaWciOiJlMjI3OWE1NTRkNTI1MDNmNWJkNjhlMGE5OTEwYzdlOTBjOWJiODE3NDRmZTljODgyNGVhMzczN2IyNzlkOWU2OWIzY2U1ZjRiNDYzYzQwMmViZTM0OTY0ZmI3YTY5NjI1ZWIwZTkxZDNkZGJkMzkyY2M4YjMyMTAzNzNkOWIwZiJ9XX0=" - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiZGMzZWE1Y2JkNmU4ZWU0MzFhZTdjMWY1MmMzZWEwOGRkOTFlMzZlMWUxYzBiMTczMjk2YmE3NjlmMjg0YjY0OSJ9LCJsZW5ndGgiOjE0OTN9fSwidmVyc2lvbiI6Mn0sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6Ijk1ODllMmMwOWQ4YWRhM2UzNjFlNWVmYzdlOGM4NmQyNzJkNjIyZDJlZDIyY2VmZTNjZDY0OWMwYWE0ZDlkYmNlMjU0ZmI4YzhmMzc2MzdjNGM2NGYwODM4MzgxNmJiNTg1MDczNGE4NjFlNjgwZmM0ZWY1YTU0NzYzNTc1MzAwIn1dfQ==", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYyIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0=" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjJ9LCJoYXNoZXMiOnsic2hhMjU2IjoiOTU4NmY0MjA3ZWQ4ZWYyOTAyODA4MmNiMmJiMmQ3MGZhYTFjNGRkMmU4OTBiMjYwZDBjNjhiMjc1ZjY1YTdjMCJ9LCJsZW5ndGgiOjE1MDN9fSwidmVyc2lvbiI6M30sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6IjA0Mjg1NTVhNzExZWYxN2E0NWY2YjU5NGVjMjQyYTEzMWU1ODVkZjRiZGMzZTM3MTA4N2YzNDU1NTIwOWQ4ZWEzMmJmN2JjYzI5MjgxMTk2NTBkYTJiZTRiNDMxNTJiNzQyMzIzOTQzMzY4MTM2ZjZjZDk4NzBmY2YyMTY3MjBmIn1dfQ==", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1tb2RpZmllZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6e30sInZlcnNpb24iOjR9LCJzaWduYXR1cmVzIjpbeyJrZXlpZCI6ImVkNzY3MmM5YTI0YWJkYTc4ODcyZWUzMmVlNzFjN2NiMWQ1MjM1ZThkYjRlY2JmMWNhMjhiOWM1MGViNzVkOWUiLCJzaWciOiIzYTBhZmEzMmViYWY0YTgzZmZlOThkMzBhOTVkYWZiNzdhNGQwZmU0ZTA1NTEyNDU0NTA2MDE0OWZhMzdkYTI4M2YxNDFlNWZkZTg5NmVhZmRhYWVkZjkxMjkzODUyMjg5MjNiOTdjY2MzNGViMjliMjZkYjc1ZDA5YzFmYTAwOSJ9XX0=" - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiZGMzZWE1Y2JkNmU4ZWU0MzFhZTdjMWY1MmMzZWEwOGRkOTFlMzZlMWUxYzBiMTczMjk2YmE3NjlmMjg0YjY0OSJ9LCJsZW5ndGgiOjE0OTN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX19LCJ2ZXJzaW9uIjo1fSwic2lnbmF0dXJlcyI6W3sia2V5aWQiOiJlZDc2NzJjOWEyNGFiZGE3ODg3MmVlMzJlZTcxYzdjYjFkNTIzNWU4ZGI0ZWNiZjFjYTI4YjljNTBlYjc1ZDllIiwic2lnIjoiMzM3ZjA4NTJkYTA3NjA1OWM5YjIxMzg2MzEwNTE3ZGU5ZmEzMjBkMzZkZGEyYWI0ODU0YzY1ZTEyZGIyZjA5YTU4ZmZlODBjYWZmZTZmNmUwZDU3MGY5YTI5ZjkzNmVmODc5ZjhiNmU2ZmM3NDQ2NWMyZTZjMTg5YTU2ZWIzMGMifV19", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1zZWNvbmQiLAogICAgIm9yZ0lkIjogMiwKICAgICJzbmFwc2hvdFByb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIyMjk1M2M4OC1lYWRjLTRmOWEtYWEwZi03ZjYyNDNmNGJmOGEiLAogICAgICAgICAgICAidHlwZSI6ICJzbmFwc2hvdCIsCiAgICAgICAgICAgICJjcmVhdGVkIjogMTYwNTA5MzA3MS4wMDAwMDAwMDAsCiAgICAgICAgICAgICJsYW5ndWFnZSI6ICJqYXZhIiwKICAgICAgICAgICAgInRhZ3MiOiBbXSwKICAgICAgICAgICAgImFjdGl2ZSI6IHRydWUsCiAgICAgICAgICAgICJ3aGVyZSI6IHsKICAgICAgICAgICAgICAgICJ0eXBlTmFtZSI6ICJjb20uZGF0YWRvZy5UYXJnZXQiLAogICAgICAgICAgICAgICAgIm1ldGhvZE5hbWUiOiAibXlNZXRob2QiLAogICAgICAgICAgICAgICAgInNpZ25hdHVyZSI6ICJqYXZhLmxhbmcuU3RyaW5nICgpIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJtZXRyaWNQcm9iZXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAiaWQiOiAiMzNhNjRkOTktZmJlZC01ZWFiLWJiMTAtODA3MzU0MDVjMDliIiwKICAgICAgICAgICAgInR5cGUiOiAibWV0cmljIiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJraW5kIjogIkNPVU5UIiwKICAgICAgICAgICAgIm1ldHJpY05hbWUiOiAiZGF0YWRvZy5kZWJ1Z2dlci5jYWxscyIsCiAgICAgICAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAgICAgICAgICJleHByIjogIiNsb2NhbFZhcjEuZmllbGQxLmZpZWxkMiIKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIF0sCiAgICAiYWxsb3dMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLmxhbmciCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZy51dGlsLk1hcCIKICAgICAgICBdCiAgICB9LAogICAgImRlbnlMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5IgogICAgICAgIF0sCiAgICAgICAgImNsYXNzZXMiOiBbCiAgICAgICAgICAgICJqYXZheC5zZWN1cml0eS5hdXRoLkF1dGhQZXJtaXNzaW9uIgogICAgICAgIF0KICAgIH0sCiAgICAic2FtcGxpbmciOiB7CiAgICAgICAgInNuYXBzaG90c1BlclNlY29uZCI6IDEuMAogICAgfQp9Cg==" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYyIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0=" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiZGMzZWE1Y2JkNmU4ZWU0MzFhZTdjMWY1MmMzZWEwOGRkOTFlMzZlMWUxYzBiMTczMjk2YmE3NjlmMjg0YjY0OSJ9LCJsZW5ndGgiOjE0OTN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctdGhpcmQvY29uZmlnIjp7ImN1c3RvbSI6eyJ2IjoxfSwiaGFzaGVzIjp7InNoYTI1NiI6Ijg1MGRkYWM3MTJkNjE1MzZkMzk2ZmU5YTUwZjBkNjMzOWU4MzBkNzgzMjYyZTAxNzJmZTk5MDk1NzgxOWE2M2MifSwibGVuZ3RoIjoxNTAwfX0sInZlcnNpb24iOjZ9LCJzaWduYXR1cmVzIjpbeyJrZXlpZCI6ImVkNzY3MmM5YTI0YWJkYTc4ODcyZWUzMmVlNzFjN2NiMWQ1MjM1ZThkYjRlY2JmMWNhMjhiOWM1MGViNzVkOWUiLCJzaWciOiI4Y2YzYWFjOTc4MThhOGE1OWJiMjc0MmU3YjEyNDg0ZDQ1YjY4OWNmOWI4YTRhZjAyNWU4OWE0NWM3NTAxZTJhMmNiMGZiNjBhMjhkODNmZDMxNTU2NDMyZmM1MWM1NTFhYzViM2UxYzJiOTNjMDE0OGFiZGEwZjRiZWJiNTUwMCJ9XX0=", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy10aGlyZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjJ9LCJoYXNoZXMiOnsic2hhMjU2IjoiOTU4NmY0MjA3ZWQ4ZWYyOTAyODA4MmNiMmJiMmQ3MGZhYTFjNGRkMmU4OTBiMjYwZDBjNjhiMjc1ZjY1YTdjMCJ9LCJsZW5ndGgiOjE1MDN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX0sImRhdGFkb2cvMi9MSVZFX0RFQlVHR0lORy9MSVZFX0RFQlVHR0lORy10aGlyZC9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiODUwZGRhYzcxMmQ2MTUzNmQzOTZmZTlhNTBmMGQ2MzM5ZTgzMGQ3ODMyNjJlMDE3MmZlOTkwOTU3ODE5YTYzYyJ9LCJsZW5ndGgiOjE1MDB9fSwidmVyc2lvbiI6N30sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6Ijk1MTU3Y2RkMzVkNWVhMDVlMTdjZmVlMDY4YzY3M2MwYTRmODA4NGM1MDAzMjhmNjdlZjk2MmU5ZjhiNDlhYmY1N2I5NGYwNzQ1ZmMxOWExZTBhYzhjYzRmMWJjYWNkZmFkNGNlYTFiNzQ2NzYyZGQ2ZGJmOTY5ZDIwMGZhZDBlIn1dfQ==", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1zZWNvbmQiLAogICAgIm9yZ0lkIjogMiwKICAgICJzbmFwc2hvdFByb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIyMjk1M2M4OC1lYWRjLTRmOWEtYWEwZi03ZjYyNDNmNGJmOGEiLAogICAgICAgICAgICAidHlwZSI6ICJzbmFwc2hvdCIsCiAgICAgICAgICAgICJjcmVhdGVkIjogMTYwNTA5MzA3MS4wMDAwMDAwMDAsCiAgICAgICAgICAgICJsYW5ndWFnZSI6ICJqYXZhIiwKICAgICAgICAgICAgInRhZ3MiOiBbXSwKICAgICAgICAgICAgImFjdGl2ZSI6IHRydWUsCiAgICAgICAgICAgICJ3aGVyZSI6IHsKICAgICAgICAgICAgICAgICJ0eXBlTmFtZSI6ICJjb20uZGF0YWRvZy5UYXJnZXQiLAogICAgICAgICAgICAgICAgIm1ldGhvZE5hbWUiOiAibXlNZXRob2QiLAogICAgICAgICAgICAgICAgInNpZ25hdHVyZSI6ICJqYXZhLmxhbmcuU3RyaW5nICgpIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJtZXRyaWNQcm9iZXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAiaWQiOiAiMzNhNjRkOTktZmJlZC01ZWFiLWJiMTAtODA3MzU0MDVjMDliIiwKICAgICAgICAgICAgInR5cGUiOiAibWV0cmljIiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJraW5kIjogIkNPVU5UIiwKICAgICAgICAgICAgIm1ldHJpY05hbWUiOiAiZGF0YWRvZy5kZWJ1Z2dlci5jYWxscyIsCiAgICAgICAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAgICAgICAgICJleHByIjogIiNsb2NhbFZhcjEuZmllbGQxLmZpZWxkMiIKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIF0sCiAgICAiYWxsb3dMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLmxhbmciCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZy51dGlsLk1hcCIKICAgICAgICBdCiAgICB9LAogICAgImRlbnlMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5IgogICAgICAgIF0sCiAgICAgICAgImNsYXNzZXMiOiBbCiAgICAgICAgICAgICJqYXZheC5zZWN1cml0eS5hdXRoLkF1dGhQZXJtaXNzaW9uIgogICAgICAgIF0KICAgIH0sCiAgICAic2FtcGxpbmciOiB7CiAgICAgICAgInNuYXBzaG90c1BlclNlY29uZCI6IDEuMAogICAgfQp9Cg==" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1tb2RpZmllZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiZGMzZWE1Y2JkNmU4ZWU0MzFhZTdjMWY1MmMzZWEwOGRkOTFlMzZlMWUxYzBiMTczMjk2YmE3NjlmMjg0YjY0OSJ9LCJsZW5ndGgiOjE0OTN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX19LCJ2ZXJzaW9uIjo4fSwic2lnbmF0dXJlcyI6W3sia2V5aWQiOiJlZDc2NzJjOWEyNGFiZGE3ODg3MmVlMzJlZTcxYzdjYjFkNTIzNWU4ZGI0ZWNiZjFjYTI4YjljNTBlYjc1ZDllIiwic2lnIjoiYmFmYjQxZGU1ZTkxMTM4MTY1ZWNiYmU5YzY1MmJkNjY5YWM5MmI2ZTBhNTJmOGM3ZmIyNzJlZjRjOTU3ZTcwODcyYmM2NWZmMWYwNWMzM2E3NWVhMDljNWY2NDQ3MDJhOWEwYjJiNjZkMWRlYmM0MWIzMzE1YzQwYTAxZWIyMDQifV19", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYyIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0=" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiZGMzZWE1Y2JkNmU4ZWU0MzFhZTdjMWY1MmMzZWEwOGRkOTFlMzZlMWUxYzBiMTczMjk2YmE3NjlmMjg0YjY0OSJ9LCJsZW5ndGgiOjE0OTN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX19LCJ2ZXJzaW9uIjo5fSwic2lnbmF0dXJlcyI6W3sia2V5aWQiOiJlZDc2NzJjOWEyNGFiZGE3ODg3MmVlMzJlZTcxYzdjYjFkNTIzNWU4ZGI0ZWNiZjFjYTI4YjljNTBlYjc1ZDllIiwic2lnIjoiZWIwZGI1MzY0NDM3ZjEwMDliMzdkNDkxZTlkMDEzYzU2MjZjMWEzMTk5MDkyYzljMTg2MmYwZDgwMzA0NjYyYTI5OWNlZjFiMDMzYjRjMTljMzU1MzMxZjllZDY1YzcyZjZjNjlmZWYwNjQzY2ZiODY1NzkzMWNhYWUxZWU1MGIifV19", - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiZGMzZWE1Y2JkNmU4ZWU0MzFhZTdjMWY1MmMzZWEwOGRkOTFlMzZlMWUxYzBiMTczMjk2YmE3NjlmMjg0YjY0OSJ9LCJsZW5ndGgiOjE0OTN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiI0NTliZDZhNDAzZDhkNTA5YzQ0M2Q3YjQ2NTVkMDI3YWRhM2NhZGUzM2U4YTM5ZjBkNTQ3ZDAyZjRkYjJkM2Q1In0sImxlbmd0aCI6OH19LCJ2ZXJzaW9uIjoxMH0sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6IjliZDgxY2EyZGJkNzQwNmIyMDc1NDJkNWNjNTYzOTIxOWQyMTA1M2JlYzI2OGQ0NWRlMDY0N2JiYTZhMzhhNDY3M2MwNmUwYTE4YjE0YzY5OGNmN2JlYjk0ZDYwOWJlMTEzZThhNmNlNjBjYTZhZDMyNzdkNmE2OTM3MWYwMTA1In1dfQ==", - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjJ9LCJoYXNoZXMiOnsic2hhMjU2IjoiOTU4NmY0MjA3ZWQ4ZWYyOTAyODA4MmNiMmJiMmQ3MGZhYTFjNGRkMmU4OTBiMjYwZDBjNjhiMjc1ZjY1YTdjMCJ9LCJsZW5ndGgiOjE1MDN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiI0NTliZDZhNDAzZDhkNTA5YzQ0M2Q3YjQ2NTVkMDI3YWRhM2NhZGUzM2U4YTM5ZjBkNTQ3ZDAyZjRkYjJkM2Q1In0sImxlbmd0aCI6OH0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnMi9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiYWZlZjkzNDJlNTZmNDQ2NTJhM2E5YWNkZjRiZGZlZGZlOGRhYjJlMDQ5Nzg4NzM0MTRmNjQzOTU0NDRmZjU0MSJ9LCJsZW5ndGgiOjEyfX0sInZlcnNpb24iOjExfSwic2lnbmF0dXJlcyI6W3sia2V5aWQiOiJlZDc2NzJjOWEyNGFiZGE3ODg3MmVlMzJlZTcxYzdjYjFkNTIzNWU4ZGI0ZWNiZjFjYTI4YjljNTBlYjc1ZDllIiwic2lnIjoiZTA1N2QyZDAzMDQ2MTQwOTllYTkyNzk4ZmYyNTcwMTZkY2ZjNjA1M2ExNWFmNmM5YTZjZGFhYWZkMTIzNTdlZTI5ZWE3MTk0YzRkY2EzM2RiNGRlMjU1OWQxZTk1MzAxZWVkYzg5YzkwOGI4ZDhhNWU3NTM4ZDc1NDI4NGM5MDAifV19", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1tb2RpZmllZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjJ9LCJoYXNoZXMiOnsic2hhMjU2IjoiOTU4NmY0MjA3ZWQ4ZWYyOTAyODA4MmNiMmJiMmQ3MGZhYTFjNGRkMmU4OTBiMjYwZDBjNjhiMjc1ZjY1YTdjMCJ9LCJsZW5ndGgiOjE1MDN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX0sImRhdGFkb2cvMi9MSVZFX0RFQlVHR0lORy9MSVZFX0RFQlVHR0lORy10aGlyZC9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiODUwZGRhYzcxMmQ2MTUzNmQzOTZmZTlhNTBmMGQ2MzM5ZTgzMGQ3ODMyNjJlMDE3MmZlOTkwOTU3ODE5YTYzYyJ9LCJsZW5ndGgiOjE1MDB9LCJkYXRhZG9nLzIvUk9HVUVfUFJPRFVDVC9teWNvbmZpZy9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiNDU5YmQ2YTQwM2Q4ZDUwOWM0NDNkN2I0NjU1ZDAyN2FkYTNjYWRlMzNlOGEzOWYwZDU0N2QwMmY0ZGIyZDNkNSJ9LCJsZW5ndGgiOjh9LCJkYXRhZG9nLzIvUk9HVUVfUFJPRFVDVC9teWNvbmZpZzIvY29uZmlnIjp7ImN1c3RvbSI6eyJ2IjoxfSwiaGFzaGVzIjp7InNoYTI1NiI6ImFmZWY5MzQyZTU2ZjQ0NjUyYTNhOWFjZGY0YmRmZWRmZThkYWIyZTA0OTc4ODczNDE0ZjY0Mzk1NDQ0ZmY1NDEifSwibGVuZ3RoIjoxMn19LCJ2ZXJzaW9uIjoxMn0sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6ImFhMjFiZjYzMTFkOWZlYzcxMzEyZDg5ZmFhNDdhODA1N2MxMjEzNDYxNmE3NzQzMTQxN2I5NDcwZDgwMmRlNDFmMDY5MGJjNTMyMGJkYzcyOWEzZjI0MzI1Y2U1YjE2OGQyNGU0NWEwZmMzZGQ2NDVkY2M1YzA0MGEwNDUzODAyIn1dfQ==", - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjJ9LCJoYXNoZXMiOnsic2hhMjU2IjoiOTU4NmY0MjA3ZWQ4ZWYyOTAyODA4MmNiMmJiMmQ3MGZhYTFjNGRkMmU4OTBiMjYwZDBjNjhiMjc1ZjY1YTdjMCJ9LCJsZW5ndGgiOjE1MDN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiI0NTliZDZhNDAzZDhkNTA5YzQ0M2Q3YjQ2NTVkMDI3YWRhM2NhZGUzM2U4YTM5ZjBkNTQ3ZDAyZjRkYjJkM2Q1In0sImxlbmd0aCI6OH0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnMi9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiYWZlZjkzNDJlNTZmNDQ2NTJhM2E5YWNkZjRiZGZlZGZlOGRhYjJlMDQ5Nzg4NzM0MTRmNjQzOTU0NDRmZjU0MSJ9LCJsZW5ndGgiOjEyfX0sInZlcnNpb24iOjEyfSwic2lnbmF0dXJlcyI6W3sia2V5aWQiOiJlZDc2NzJjOWEyNGFiZGE3ODg3MmVlMzJlZTcxYzdjYjFkNTIzNWU4ZGI0ZWNiZjFjYTI4YjljNTBlYjc1ZDllIiwic2lnIjoiMGQ1OGMwY2JlNTQ3NjA5N2Q0MzZjYmM0NzAzZWZiYmRmNTQxYjk2OTdjNDZlN2NmNjQ3MTE4MjA1OTY0OThjNGFjMzBjNjk2NWExNTVkYjAwYjA4MTVkNWQxYWFlOWUzZGFiZGQ1MmU1NjA0MDM2ZWVkNjQwZjRkOTkxYWI4MDkifV19", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy10aGlyZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjJ9LCJoYXNoZXMiOnsic2hhMjU2IjoiOTU4NmY0MjA3ZWQ4ZWYyOTAyODA4MmNiMmJiMmQ3MGZhYTFjNGRkMmU4OTBiMjYwZDBjNjhiMjc1ZjY1YTdjMCJ9LCJsZW5ndGgiOjE1MDN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX0sImRhdGFkb2cvMi9MSVZFX0RFQlVHR0lORy9MSVZFX0RFQlVHR0lORy10aGlyZC90ZXN0bmFtZSI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiI4NTBkZGFjNzEyZDYxNTM2ZDM5NmZlOWE1MGYwZDYzMzllODMwZDc4MzI2MmUwMTcyZmU5OTA5NTc4MTlhNjNjIn0sImxlbmd0aCI6MTUwMH0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiI0NTliZDZhNDAzZDhkNTA5YzQ0M2Q3YjQ2NTVkMDI3YWRhM2NhZGUzM2U4YTM5ZjBkNTQ3ZDAyZjRkYjJkM2Q1In0sImxlbmd0aCI6OH0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnMi9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiYWZlZjkzNDJlNTZmNDQ2NTJhM2E5YWNkZjRiZGZlZGZlOGRhYjJlMDQ5Nzg4NzM0MTRmNjQzOTU0NDRmZjU0MSJ9LCJsZW5ndGgiOjEyfX0sInZlcnNpb24iOjEyfSwic2lnbmF0dXJlcyI6W3sia2V5aWQiOiJlZDc2NzJjOWEyNGFiZGE3ODg3MmVlMzJlZTcxYzdjYjFkNTIzNWU4ZGI0ZWNiZjFjYTI4YjljNTBlYjc1ZDllIiwic2lnIjoiZTY3NWVjY2Y1YTJjOGZiOWI5Mjc5ZjQ5YWI1YTA1NGJmMzEwYjM5MGY4ODA4OGY1Y2RkNDFiZTM3ZjhhYzUyZDhhYmNhYzRmYWUyNjY0NDRiMDNiMjRmNzljYTM1ZGJkYWNiMzZlNGI3MDI0ODRmYWI5YWMzOTNlZmMxYTk5MGIifV19", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/testname", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy10aGlyZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/testname" - ] - }, - {} -] diff --git a/utils/proxy/rc_mocked_responses_live_debugging_nocache.json b/utils/proxy/rc_mocked_responses_live_debugging_nocache.json deleted file mode 100644 index f3753eccf59..00000000000 --- a/utils/proxy/rc_mocked_responses_live_debugging_nocache.json +++ /dev/null @@ -1,219 +0,0 @@ -[ - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6e30sInZlcnNpb24iOjF9LCJzaWduYXR1cmVzIjpbeyJrZXlpZCI6ImVkNzY3MmM5YTI0YWJkYTc4ODcyZWUzMmVlNzFjN2NiMWQ1MjM1ZThkYjRlY2JmMWNhMjhiOWM1MGViNzVkOWUiLCJzaWciOiJlMjI3OWE1NTRkNTI1MDNmNWJkNjhlMGE5OTEwYzdlOTBjOWJiODE3NDRmZTljODgyNGVhMzczN2IyNzlkOWU2OWIzY2U1ZjRiNDYzYzQwMmViZTM0OTY0ZmI3YTY5NjI1ZWIwZTkxZDNkZGJkMzkyY2M4YjMyMTAzNzNkOWIwZiJ9XX0=" - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiZGMzZWE1Y2JkNmU4ZWU0MzFhZTdjMWY1MmMzZWEwOGRkOTFlMzZlMWUxYzBiMTczMjk2YmE3NjlmMjg0YjY0OSJ9LCJsZW5ndGgiOjE0OTN9fSwidmVyc2lvbiI6Mn0sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6Ijk1ODllMmMwOWQ4YWRhM2UzNjFlNWVmYzdlOGM4NmQyNzJkNjIyZDJlZDIyY2VmZTNjZDY0OWMwYWE0ZDlkYmNlMjU0ZmI4YzhmMzc2MzdjNGM2NGYwODM4MzgxNmJiNTg1MDczNGE4NjFlNjgwZmM0ZWY1YTU0NzYzNTc1MzAwIn1dfQ==", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYyIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0=" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjJ9LCJoYXNoZXMiOnsic2hhMjU2IjoiOTU4NmY0MjA3ZWQ4ZWYyOTAyODA4MmNiMmJiMmQ3MGZhYTFjNGRkMmU4OTBiMjYwZDBjNjhiMjc1ZjY1YTdjMCJ9LCJsZW5ndGgiOjE1MDN9fSwidmVyc2lvbiI6M30sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6IjA0Mjg1NTVhNzExZWYxN2E0NWY2YjU5NGVjMjQyYTEzMWU1ODVkZjRiZGMzZTM3MTA4N2YzNDU1NTIwOWQ4ZWEzMmJmN2JjYzI5MjgxMTk2NTBkYTJiZTRiNDMxNTJiNzQyMzIzOTQzMzY4MTM2ZjZjZDk4NzBmY2YyMTY3MjBmIn1dfQ==", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1tb2RpZmllZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6e30sInZlcnNpb24iOjR9LCJzaWduYXR1cmVzIjpbeyJrZXlpZCI6ImVkNzY3MmM5YTI0YWJkYTc4ODcyZWUzMmVlNzFjN2NiMWQ1MjM1ZThkYjRlY2JmMWNhMjhiOWM1MGViNzVkOWUiLCJzaWciOiIzYTBhZmEzMmViYWY0YTgzZmZlOThkMzBhOTVkYWZiNzdhNGQwZmU0ZTA1NTEyNDU0NTA2MDE0OWZhMzdkYTI4M2YxNDFlNWZkZTg5NmVhZmRhYWVkZjkxMjkzODUyMjg5MjNiOTdjY2MzNGViMjliMjZkYjc1ZDA5YzFmYTAwOSJ9XX0=" - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiZGMzZWE1Y2JkNmU4ZWU0MzFhZTdjMWY1MmMzZWEwOGRkOTFlMzZlMWUxYzBiMTczMjk2YmE3NjlmMjg0YjY0OSJ9LCJsZW5ndGgiOjE0OTN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX19LCJ2ZXJzaW9uIjo1fSwic2lnbmF0dXJlcyI6W3sia2V5aWQiOiJlZDc2NzJjOWEyNGFiZGE3ODg3MmVlMzJlZTcxYzdjYjFkNTIzNWU4ZGI0ZWNiZjFjYTI4YjljNTBlYjc1ZDllIiwic2lnIjoiMzM3ZjA4NTJkYTA3NjA1OWM5YjIxMzg2MzEwNTE3ZGU5ZmEzMjBkMzZkZGEyYWI0ODU0YzY1ZTEyZGIyZjA5YTU4ZmZlODBjYWZmZTZmNmUwZDU3MGY5YTI5ZjkzNmVmODc5ZjhiNmU2ZmM3NDQ2NWMyZTZjMTg5YTU2ZWIzMGMifV19", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1zZWNvbmQiLAogICAgIm9yZ0lkIjogMiwKICAgICJzbmFwc2hvdFByb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIyMjk1M2M4OC1lYWRjLTRmOWEtYWEwZi03ZjYyNDNmNGJmOGEiLAogICAgICAgICAgICAidHlwZSI6ICJzbmFwc2hvdCIsCiAgICAgICAgICAgICJjcmVhdGVkIjogMTYwNTA5MzA3MS4wMDAwMDAwMDAsCiAgICAgICAgICAgICJsYW5ndWFnZSI6ICJqYXZhIiwKICAgICAgICAgICAgInRhZ3MiOiBbXSwKICAgICAgICAgICAgImFjdGl2ZSI6IHRydWUsCiAgICAgICAgICAgICJ3aGVyZSI6IHsKICAgICAgICAgICAgICAgICJ0eXBlTmFtZSI6ICJjb20uZGF0YWRvZy5UYXJnZXQiLAogICAgICAgICAgICAgICAgIm1ldGhvZE5hbWUiOiAibXlNZXRob2QiLAogICAgICAgICAgICAgICAgInNpZ25hdHVyZSI6ICJqYXZhLmxhbmcuU3RyaW5nICgpIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJtZXRyaWNQcm9iZXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAiaWQiOiAiMzNhNjRkOTktZmJlZC01ZWFiLWJiMTAtODA3MzU0MDVjMDliIiwKICAgICAgICAgICAgInR5cGUiOiAibWV0cmljIiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJraW5kIjogIkNPVU5UIiwKICAgICAgICAgICAgIm1ldHJpY05hbWUiOiAiZGF0YWRvZy5kZWJ1Z2dlci5jYWxscyIsCiAgICAgICAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAgICAgICAgICJleHByIjogIiNsb2NhbFZhcjEuZmllbGQxLmZpZWxkMiIKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIF0sCiAgICAiYWxsb3dMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLmxhbmciCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZy51dGlsLk1hcCIKICAgICAgICBdCiAgICB9LAogICAgImRlbnlMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5IgogICAgICAgIF0sCiAgICAgICAgImNsYXNzZXMiOiBbCiAgICAgICAgICAgICJqYXZheC5zZWN1cml0eS5hdXRoLkF1dGhQZXJtaXNzaW9uIgogICAgICAgIF0KICAgIH0sCiAgICAic2FtcGxpbmciOiB7CiAgICAgICAgInNuYXBzaG90c1BlclNlY29uZCI6IDEuMAogICAgfQp9Cg==" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYyIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0=" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiZGMzZWE1Y2JkNmU4ZWU0MzFhZTdjMWY1MmMzZWEwOGRkOTFlMzZlMWUxYzBiMTczMjk2YmE3NjlmMjg0YjY0OSJ9LCJsZW5ndGgiOjE0OTN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctdGhpcmQvY29uZmlnIjp7ImN1c3RvbSI6eyJ2IjoxfSwiaGFzaGVzIjp7InNoYTI1NiI6Ijg1MGRkYWM3MTJkNjE1MzZkMzk2ZmU5YTUwZjBkNjMzOWU4MzBkNzgzMjYyZTAxNzJmZTk5MDk1NzgxOWE2M2MifSwibGVuZ3RoIjoxNTAwfX0sInZlcnNpb24iOjZ9LCJzaWduYXR1cmVzIjpbeyJrZXlpZCI6ImVkNzY3MmM5YTI0YWJkYTc4ODcyZWUzMmVlNzFjN2NiMWQ1MjM1ZThkYjRlY2JmMWNhMjhiOWM1MGViNzVkOWUiLCJzaWciOiI4Y2YzYWFjOTc4MThhOGE1OWJiMjc0MmU3YjEyNDg0ZDQ1YjY4OWNmOWI4YTRhZjAyNWU4OWE0NWM3NTAxZTJhMmNiMGZiNjBhMjhkODNmZDMxNTU2NDMyZmM1MWM1NTFhYzViM2UxYzJiOTNjMDE0OGFiZGEwZjRiZWJiNTUwMCJ9XX0=", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy10aGlyZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYyIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0=" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjJ9LCJoYXNoZXMiOnsic2hhMjU2IjoiOTU4NmY0MjA3ZWQ4ZWYyOTAyODA4MmNiMmJiMmQ3MGZhYTFjNGRkMmU4OTBiMjYwZDBjNjhiMjc1ZjY1YTdjMCJ9LCJsZW5ndGgiOjE1MDN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX0sImRhdGFkb2cvMi9MSVZFX0RFQlVHR0lORy9MSVZFX0RFQlVHR0lORy10aGlyZC9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiODUwZGRhYzcxMmQ2MTUzNmQzOTZmZTlhNTBmMGQ2MzM5ZTgzMGQ3ODMyNjJlMDE3MmZlOTkwOTU3ODE5YTYzYyJ9LCJsZW5ndGgiOjE1MDB9fSwidmVyc2lvbiI6N30sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6Ijk1MTU3Y2RkMzVkNWVhMDVlMTdjZmVlMDY4YzY3M2MwYTRmODA4NGM1MDAzMjhmNjdlZjk2MmU5ZjhiNDlhYmY1N2I5NGYwNzQ1ZmMxOWExZTBhYzhjYzRmMWJjYWNkZmFkNGNlYTFiNzQ2NzYyZGQ2ZGJmOTY5ZDIwMGZhZDBlIn1dfQ==", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy10aGlyZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1zZWNvbmQiLAogICAgIm9yZ0lkIjogMiwKICAgICJzbmFwc2hvdFByb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIyMjk1M2M4OC1lYWRjLTRmOWEtYWEwZi03ZjYyNDNmNGJmOGEiLAogICAgICAgICAgICAidHlwZSI6ICJzbmFwc2hvdCIsCiAgICAgICAgICAgICJjcmVhdGVkIjogMTYwNTA5MzA3MS4wMDAwMDAwMDAsCiAgICAgICAgICAgICJsYW5ndWFnZSI6ICJqYXZhIiwKICAgICAgICAgICAgInRhZ3MiOiBbXSwKICAgICAgICAgICAgImFjdGl2ZSI6IHRydWUsCiAgICAgICAgICAgICJ3aGVyZSI6IHsKICAgICAgICAgICAgICAgICJ0eXBlTmFtZSI6ICJjb20uZGF0YWRvZy5UYXJnZXQiLAogICAgICAgICAgICAgICAgIm1ldGhvZE5hbWUiOiAibXlNZXRob2QiLAogICAgICAgICAgICAgICAgInNpZ25hdHVyZSI6ICJqYXZhLmxhbmcuU3RyaW5nICgpIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJtZXRyaWNQcm9iZXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAiaWQiOiAiMzNhNjRkOTktZmJlZC01ZWFiLWJiMTAtODA3MzU0MDVjMDliIiwKICAgICAgICAgICAgInR5cGUiOiAibWV0cmljIiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJraW5kIjogIkNPVU5UIiwKICAgICAgICAgICAgIm1ldHJpY05hbWUiOiAiZGF0YWRvZy5kZWJ1Z2dlci5jYWxscyIsCiAgICAgICAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAgICAgICAgICJleHByIjogIiNsb2NhbFZhcjEuZmllbGQxLmZpZWxkMiIKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIF0sCiAgICAiYWxsb3dMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLmxhbmciCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZy51dGlsLk1hcCIKICAgICAgICBdCiAgICB9LAogICAgImRlbnlMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5IgogICAgICAgIF0sCiAgICAgICAgImNsYXNzZXMiOiBbCiAgICAgICAgICAgICJqYXZheC5zZWN1cml0eS5hdXRoLkF1dGhQZXJtaXNzaW9uIgogICAgICAgIF0KICAgIH0sCiAgICAic2FtcGxpbmciOiB7CiAgICAgICAgInNuYXBzaG90c1BlclNlY29uZCI6IDEuMAogICAgfQp9Cg==" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1tb2RpZmllZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiZGMzZWE1Y2JkNmU4ZWU0MzFhZTdjMWY1MmMzZWEwOGRkOTFlMzZlMWUxYzBiMTczMjk2YmE3NjlmMjg0YjY0OSJ9LCJsZW5ndGgiOjE0OTN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX19LCJ2ZXJzaW9uIjo4fSwic2lnbmF0dXJlcyI6W3sia2V5aWQiOiJlZDc2NzJjOWEyNGFiZGE3ODg3MmVlMzJlZTcxYzdjYjFkNTIzNWU4ZGI0ZWNiZjFjYTI4YjljNTBlYjc1ZDllIiwic2lnIjoiYmFmYjQxZGU1ZTkxMTM4MTY1ZWNiYmU5YzY1MmJkNjY5YWM5MmI2ZTBhNTJmOGM3ZmIyNzJlZjRjOTU3ZTcwODcyYmM2NWZmMWYwNWMzM2E3NWVhMDljNWY2NDQ3MDJhOWEwYjJiNjZkMWRlYmM0MWIzMzE1YzQwYTAxZWIyMDQifV19", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1zZWNvbmQiLAogICAgIm9yZ0lkIjogMiwKICAgICJzbmFwc2hvdFByb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIyMjk1M2M4OC1lYWRjLTRmOWEtYWEwZi03ZjYyNDNmNGJmOGEiLAogICAgICAgICAgICAidHlwZSI6ICJzbmFwc2hvdCIsCiAgICAgICAgICAgICJjcmVhdGVkIjogMTYwNTA5MzA3MS4wMDAwMDAwMDAsCiAgICAgICAgICAgICJsYW5ndWFnZSI6ICJqYXZhIiwKICAgICAgICAgICAgInRhZ3MiOiBbXSwKICAgICAgICAgICAgImFjdGl2ZSI6IHRydWUsCiAgICAgICAgICAgICJ3aGVyZSI6IHsKICAgICAgICAgICAgICAgICJ0eXBlTmFtZSI6ICJjb20uZGF0YWRvZy5UYXJnZXQiLAogICAgICAgICAgICAgICAgIm1ldGhvZE5hbWUiOiAibXlNZXRob2QiLAogICAgICAgICAgICAgICAgInNpZ25hdHVyZSI6ICJqYXZhLmxhbmcuU3RyaW5nICgpIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJtZXRyaWNQcm9iZXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAiaWQiOiAiMzNhNjRkOTktZmJlZC01ZWFiLWJiMTAtODA3MzU0MDVjMDliIiwKICAgICAgICAgICAgInR5cGUiOiAibWV0cmljIiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJraW5kIjogIkNPVU5UIiwKICAgICAgICAgICAgIm1ldHJpY05hbWUiOiAiZGF0YWRvZy5kZWJ1Z2dlci5jYWxscyIsCiAgICAgICAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAgICAgICAgICJleHByIjogIiNsb2NhbFZhcjEuZmllbGQxLmZpZWxkMiIKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIF0sCiAgICAiYWxsb3dMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLmxhbmciCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZy51dGlsLk1hcCIKICAgICAgICBdCiAgICB9LAogICAgImRlbnlMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5IgogICAgICAgIF0sCiAgICAgICAgImNsYXNzZXMiOiBbCiAgICAgICAgICAgICJqYXZheC5zZWN1cml0eS5hdXRoLkF1dGhQZXJtaXNzaW9uIgogICAgICAgIF0KICAgIH0sCiAgICAic2FtcGxpbmciOiB7CiAgICAgICAgInNuYXBzaG90c1BlclNlY29uZCI6IDEuMAogICAgfQp9Cg==" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYyIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0=" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiZGMzZWE1Y2JkNmU4ZWU0MzFhZTdjMWY1MmMzZWEwOGRkOTFlMzZlMWUxYzBiMTczMjk2YmE3NjlmMjg0YjY0OSJ9LCJsZW5ndGgiOjE0OTN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX19LCJ2ZXJzaW9uIjo5fSwic2lnbmF0dXJlcyI6W3sia2V5aWQiOiJlZDc2NzJjOWEyNGFiZGE3ODg3MmVlMzJlZTcxYzdjYjFkNTIzNWU4ZGI0ZWNiZjFjYTI4YjljNTBlYjc1ZDllIiwic2lnIjoiZWIwZGI1MzY0NDM3ZjEwMDliMzdkNDkxZTlkMDEzYzU2MjZjMWEzMTk5MDkyYzljMTg2MmYwZDgwMzA0NjYyYTI5OWNlZjFiMDMzYjRjMTljMzU1MzMxZjllZDY1YzcyZjZjNjlmZWYwNjQzY2ZiODY1NzkzMWNhYWUxZWU1MGIifV19", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1zZWNvbmQiLAogICAgIm9yZ0lkIjogMiwKICAgICJzbmFwc2hvdFByb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIyMjk1M2M4OC1lYWRjLTRmOWEtYWEwZi03ZjYyNDNmNGJmOGEiLAogICAgICAgICAgICAidHlwZSI6ICJzbmFwc2hvdCIsCiAgICAgICAgICAgICJjcmVhdGVkIjogMTYwNTA5MzA3MS4wMDAwMDAwMDAsCiAgICAgICAgICAgICJsYW5ndWFnZSI6ICJqYXZhIiwKICAgICAgICAgICAgInRhZ3MiOiBbXSwKICAgICAgICAgICAgImFjdGl2ZSI6IHRydWUsCiAgICAgICAgICAgICJ3aGVyZSI6IHsKICAgICAgICAgICAgICAgICJ0eXBlTmFtZSI6ICJjb20uZGF0YWRvZy5UYXJnZXQiLAogICAgICAgICAgICAgICAgIm1ldGhvZE5hbWUiOiAibXlNZXRob2QiLAogICAgICAgICAgICAgICAgInNpZ25hdHVyZSI6ICJqYXZhLmxhbmcuU3RyaW5nICgpIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJtZXRyaWNQcm9iZXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAiaWQiOiAiMzNhNjRkOTktZmJlZC01ZWFiLWJiMTAtODA3MzU0MDVjMDliIiwKICAgICAgICAgICAgInR5cGUiOiAibWV0cmljIiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJraW5kIjogIkNPVU5UIiwKICAgICAgICAgICAgIm1ldHJpY05hbWUiOiAiZGF0YWRvZy5kZWJ1Z2dlci5jYWxscyIsCiAgICAgICAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAgICAgICAgICJleHByIjogIiNsb2NhbFZhcjEuZmllbGQxLmZpZWxkMiIKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIF0sCiAgICAiYWxsb3dMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLmxhbmciCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZy51dGlsLk1hcCIKICAgICAgICBdCiAgICB9LAogICAgImRlbnlMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5IgogICAgICAgIF0sCiAgICAgICAgImNsYXNzZXMiOiBbCiAgICAgICAgICAgICJqYXZheC5zZWN1cml0eS5hdXRoLkF1dGhQZXJtaXNzaW9uIgogICAgICAgIF0KICAgIH0sCiAgICAic2FtcGxpbmciOiB7CiAgICAgICAgInNuYXBzaG90c1BlclNlY29uZCI6IDEuMAogICAgfQp9Cg==" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYyIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0=" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiZGMzZWE1Y2JkNmU4ZWU0MzFhZTdjMWY1MmMzZWEwOGRkOTFlMzZlMWUxYzBiMTczMjk2YmE3NjlmMjg0YjY0OSJ9LCJsZW5ndGgiOjE0OTN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiI0NTliZDZhNDAzZDhkNTA5YzQ0M2Q3YjQ2NTVkMDI3YWRhM2NhZGUzM2U4YTM5ZjBkNTQ3ZDAyZjRkYjJkM2Q1In0sImxlbmd0aCI6OH19LCJ2ZXJzaW9uIjoxMH0sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6IjliZDgxY2EyZGJkNzQwNmIyMDc1NDJkNWNjNTYzOTIxOWQyMTA1M2JlYzI2OGQ0NWRlMDY0N2JiYTZhMzhhNDY3M2MwNmUwYTE4YjE0YzY5OGNmN2JlYjk0ZDYwOWJlMTEzZThhNmNlNjBjYTZhZDMyNzdkNmE2OTM3MWYwMTA1In1dfQ==", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1zZWNvbmQiLAogICAgIm9yZ0lkIjogMiwKICAgICJzbmFwc2hvdFByb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIyMjk1M2M4OC1lYWRjLTRmOWEtYWEwZi03ZjYyNDNmNGJmOGEiLAogICAgICAgICAgICAidHlwZSI6ICJzbmFwc2hvdCIsCiAgICAgICAgICAgICJjcmVhdGVkIjogMTYwNTA5MzA3MS4wMDAwMDAwMDAsCiAgICAgICAgICAgICJsYW5ndWFnZSI6ICJqYXZhIiwKICAgICAgICAgICAgInRhZ3MiOiBbXSwKICAgICAgICAgICAgImFjdGl2ZSI6IHRydWUsCiAgICAgICAgICAgICJ3aGVyZSI6IHsKICAgICAgICAgICAgICAgICJ0eXBlTmFtZSI6ICJjb20uZGF0YWRvZy5UYXJnZXQiLAogICAgICAgICAgICAgICAgIm1ldGhvZE5hbWUiOiAibXlNZXRob2QiLAogICAgICAgICAgICAgICAgInNpZ25hdHVyZSI6ICJqYXZhLmxhbmcuU3RyaW5nICgpIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJtZXRyaWNQcm9iZXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAiaWQiOiAiMzNhNjRkOTktZmJlZC01ZWFiLWJiMTAtODA3MzU0MDVjMDliIiwKICAgICAgICAgICAgInR5cGUiOiAibWV0cmljIiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJraW5kIjogIkNPVU5UIiwKICAgICAgICAgICAgIm1ldHJpY05hbWUiOiAiZGF0YWRvZy5kZWJ1Z2dlci5jYWxscyIsCiAgICAgICAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAgICAgICAgICJleHByIjogIiNsb2NhbFZhcjEuZmllbGQxLmZpZWxkMiIKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIF0sCiAgICAiYWxsb3dMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLmxhbmciCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZy51dGlsLk1hcCIKICAgICAgICBdCiAgICB9LAogICAgImRlbnlMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5IgogICAgICAgIF0sCiAgICAgICAgImNsYXNzZXMiOiBbCiAgICAgICAgICAgICJqYXZheC5zZWN1cml0eS5hdXRoLkF1dGhQZXJtaXNzaW9uIgogICAgICAgIF0KICAgIH0sCiAgICAic2FtcGxpbmciOiB7CiAgICAgICAgInNuYXBzaG90c1BlclNlY29uZCI6IDEuMAogICAgfQp9Cg==" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYyIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0=" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjJ9LCJoYXNoZXMiOnsic2hhMjU2IjoiOTU4NmY0MjA3ZWQ4ZWYyOTAyODA4MmNiMmJiMmQ3MGZhYTFjNGRkMmU4OTBiMjYwZDBjNjhiMjc1ZjY1YTdjMCJ9LCJsZW5ndGgiOjE1MDN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiI0NTliZDZhNDAzZDhkNTA5YzQ0M2Q3YjQ2NTVkMDI3YWRhM2NhZGUzM2U4YTM5ZjBkNTQ3ZDAyZjRkYjJkM2Q1In0sImxlbmd0aCI6OH0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnMi9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiYWZlZjkzNDJlNTZmNDQ2NTJhM2E5YWNkZjRiZGZlZGZlOGRhYjJlMDQ5Nzg4NzM0MTRmNjQzOTU0NDRmZjU0MSJ9LCJsZW5ndGgiOjEyfX0sInZlcnNpb24iOjExfSwic2lnbmF0dXJlcyI6W3sia2V5aWQiOiJlZDc2NzJjOWEyNGFiZGE3ODg3MmVlMzJlZTcxYzdjYjFkNTIzNWU4ZGI0ZWNiZjFjYTI4YjljNTBlYjc1ZDllIiwic2lnIjoiZTA1N2QyZDAzMDQ2MTQwOTllYTkyNzk4ZmYyNTcwMTZkY2ZjNjA1M2ExNWFmNmM5YTZjZGFhYWZkMTIzNTdlZTI5ZWE3MTk0YzRkY2EzM2RiNGRlMjU1OWQxZTk1MzAxZWVkYzg5YzkwOGI4ZDhhNWU3NTM4ZDc1NDI4NGM5MDAifV19", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1zZWNvbmQiLAogICAgIm9yZ0lkIjogMiwKICAgICJzbmFwc2hvdFByb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIyMjk1M2M4OC1lYWRjLTRmOWEtYWEwZi03ZjYyNDNmNGJmOGEiLAogICAgICAgICAgICAidHlwZSI6ICJzbmFwc2hvdCIsCiAgICAgICAgICAgICJjcmVhdGVkIjogMTYwNTA5MzA3MS4wMDAwMDAwMDAsCiAgICAgICAgICAgICJsYW5ndWFnZSI6ICJqYXZhIiwKICAgICAgICAgICAgInRhZ3MiOiBbXSwKICAgICAgICAgICAgImFjdGl2ZSI6IHRydWUsCiAgICAgICAgICAgICJ3aGVyZSI6IHsKICAgICAgICAgICAgICAgICJ0eXBlTmFtZSI6ICJjb20uZGF0YWRvZy5UYXJnZXQiLAogICAgICAgICAgICAgICAgIm1ldGhvZE5hbWUiOiAibXlNZXRob2QiLAogICAgICAgICAgICAgICAgInNpZ25hdHVyZSI6ICJqYXZhLmxhbmcuU3RyaW5nICgpIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJtZXRyaWNQcm9iZXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAiaWQiOiAiMzNhNjRkOTktZmJlZC01ZWFiLWJiMTAtODA3MzU0MDVjMDliIiwKICAgICAgICAgICAgInR5cGUiOiAibWV0cmljIiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJraW5kIjogIkNPVU5UIiwKICAgICAgICAgICAgIm1ldHJpY05hbWUiOiAiZGF0YWRvZy5kZWJ1Z2dlci5jYWxscyIsCiAgICAgICAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAgICAgICAgICJleHByIjogIiNsb2NhbFZhcjEuZmllbGQxLmZpZWxkMiIKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIF0sCiAgICAiYWxsb3dMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLmxhbmciCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZy51dGlsLk1hcCIKICAgICAgICBdCiAgICB9LAogICAgImRlbnlMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5IgogICAgICAgIF0sCiAgICAgICAgImNsYXNzZXMiOiBbCiAgICAgICAgICAgICJqYXZheC5zZWN1cml0eS5hdXRoLkF1dGhQZXJtaXNzaW9uIgogICAgICAgIF0KICAgIH0sCiAgICAic2FtcGxpbmciOiB7CiAgICAgICAgInNuYXBzaG90c1BlclNlY29uZCI6IDEuMAogICAgfQp9Cg==" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1tb2RpZmllZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjJ9LCJoYXNoZXMiOnsic2hhMjU2IjoiOTU4NmY0MjA3ZWQ4ZWYyOTAyODA4MmNiMmJiMmQ3MGZhYTFjNGRkMmU4OTBiMjYwZDBjNjhiMjc1ZjY1YTdjMCJ9LCJsZW5ndGgiOjE1MDN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX0sImRhdGFkb2cvMi9MSVZFX0RFQlVHR0lORy9MSVZFX0RFQlVHR0lORy10aGlyZC9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiODUwZGRhYzcxMmQ2MTUzNmQzOTZmZTlhNTBmMGQ2MzM5ZTgzMGQ3ODMyNjJlMDE3MmZlOTkwOTU3ODE5YTYzYyJ9LCJsZW5ndGgiOjE1MDB9LCJkYXRhZG9nLzIvUk9HVUVfUFJPRFVDVC9teWNvbmZpZy9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiNDU5YmQ2YTQwM2Q4ZDUwOWM0NDNkN2I0NjU1ZDAyN2FkYTNjYWRlMzNlOGEzOWYwZDU0N2QwMmY0ZGIyZDNkNSJ9LCJsZW5ndGgiOjh9LCJkYXRhZG9nLzIvUk9HVUVfUFJPRFVDVC9teWNvbmZpZzIvY29uZmlnIjp7ImN1c3RvbSI6eyJ2IjoxfSwiaGFzaGVzIjp7InNoYTI1NiI6ImFmZWY5MzQyZTU2ZjQ0NjUyYTNhOWFjZGY0YmRmZWRmZThkYWIyZTA0OTc4ODczNDE0ZjY0Mzk1NDQ0ZmY1NDEifSwibGVuZ3RoIjoxMn19LCJ2ZXJzaW9uIjoxMn0sInNpZ25hdHVyZXMiOlt7ImtleWlkIjoiZWQ3NjcyYzlhMjRhYmRhNzg4NzJlZTMyZWU3MWM3Y2IxZDUyMzVlOGRiNGVjYmYxY2EyOGI5YzUwZWI3NWQ5ZSIsInNpZyI6ImFhMjFiZjYzMTFkOWZlYzcxMzEyZDg5ZmFhNDdhODA1N2MxMjEzNDYxNmE3NzQzMTQxN2I5NDcwZDgwMmRlNDFmMDY5MGJjNTMyMGJkYzcyOWEzZjI0MzI1Y2U1YjE2OGQyNGU0NWEwZmMzZGQ2NDVkY2M1YzA0MGEwNDUzODAyIn1dfQ==", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1zZWNvbmQiLAogICAgIm9yZ0lkIjogMiwKICAgICJzbmFwc2hvdFByb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIyMjk1M2M4OC1lYWRjLTRmOWEtYWEwZi03ZjYyNDNmNGJmOGEiLAogICAgICAgICAgICAidHlwZSI6ICJzbmFwc2hvdCIsCiAgICAgICAgICAgICJjcmVhdGVkIjogMTYwNTA5MzA3MS4wMDAwMDAwMDAsCiAgICAgICAgICAgICJsYW5ndWFnZSI6ICJqYXZhIiwKICAgICAgICAgICAgInRhZ3MiOiBbXSwKICAgICAgICAgICAgImFjdGl2ZSI6IHRydWUsCiAgICAgICAgICAgICJ3aGVyZSI6IHsKICAgICAgICAgICAgICAgICJ0eXBlTmFtZSI6ICJjb20uZGF0YWRvZy5UYXJnZXQiLAogICAgICAgICAgICAgICAgIm1ldGhvZE5hbWUiOiAibXlNZXRob2QiLAogICAgICAgICAgICAgICAgInNpZ25hdHVyZSI6ICJqYXZhLmxhbmcuU3RyaW5nICgpIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJtZXRyaWNQcm9iZXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAiaWQiOiAiMzNhNjRkOTktZmJlZC01ZWFiLWJiMTAtODA3MzU0MDVjMDliIiwKICAgICAgICAgICAgInR5cGUiOiAibWV0cmljIiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJraW5kIjogIkNPVU5UIiwKICAgICAgICAgICAgIm1ldHJpY05hbWUiOiAiZGF0YWRvZy5kZWJ1Z2dlci5jYWxscyIsCiAgICAgICAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAgICAgICAgICJleHByIjogIiNsb2NhbFZhcjEuZmllbGQxLmZpZWxkMiIKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIF0sCiAgICAiYWxsb3dMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLmxhbmciCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZy51dGlsLk1hcCIKICAgICAgICBdCiAgICB9LAogICAgImRlbnlMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5IgogICAgICAgIF0sCiAgICAgICAgImNsYXNzZXMiOiBbCiAgICAgICAgICAgICJqYXZheC5zZWN1cml0eS5hdXRoLkF1dGhQZXJtaXNzaW9uIgogICAgICAgIF0KICAgIH0sCiAgICAic2FtcGxpbmciOiB7CiAgICAgICAgInNuYXBzaG90c1BlclNlY29uZCI6IDEuMAogICAgfQp9Cg==" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1tb2RpZmllZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjJ9LCJoYXNoZXMiOnsic2hhMjU2IjoiOTU4NmY0MjA3ZWQ4ZWYyOTAyODA4MmNiMmJiMmQ3MGZhYTFjNGRkMmU4OTBiMjYwZDBjNjhiMjc1ZjY1YTdjMCJ9LCJsZW5ndGgiOjE1MDN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiI0NTliZDZhNDAzZDhkNTA5YzQ0M2Q3YjQ2NTVkMDI3YWRhM2NhZGUzM2U4YTM5ZjBkNTQ3ZDAyZjRkYjJkM2Q1In0sImxlbmd0aCI6OH0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnMi9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiYWZlZjkzNDJlNTZmNDQ2NTJhM2E5YWNkZjRiZGZlZGZlOGRhYjJlMDQ5Nzg4NzM0MTRmNjQzOTU0NDRmZjU0MSJ9LCJsZW5ndGgiOjEyfX0sInZlcnNpb24iOjEyfSwic2lnbmF0dXJlcyI6W3sia2V5aWQiOiJlZDc2NzJjOWEyNGFiZGE3ODg3MmVlMzJlZTcxYzdjYjFkNTIzNWU4ZGI0ZWNiZjFjYTI4YjljNTBlYjc1ZDllIiwic2lnIjoiMGQ1OGMwY2JlNTQ3NjA5N2Q0MzZjYmM0NzAzZWZiYmRmNTQxYjk2OTdjNDZlN2NmNjQ3MTE4MjA1OTY0OThjNGFjMzBjNjk2NWExNTVkYjAwYjA4MTVkNWQxYWFlOWUzZGFiZGQ1MmU1NjA0MDM2ZWVkNjQwZjRkOTkxYWI4MDkifV19", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy10aGlyZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1zZWNvbmQiLAogICAgIm9yZ0lkIjogMiwKICAgICJzbmFwc2hvdFByb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIyMjk1M2M4OC1lYWRjLTRmOWEtYWEwZi03ZjYyNDNmNGJmOGEiLAogICAgICAgICAgICAidHlwZSI6ICJzbmFwc2hvdCIsCiAgICAgICAgICAgICJjcmVhdGVkIjogMTYwNTA5MzA3MS4wMDAwMDAwMDAsCiAgICAgICAgICAgICJsYW5ndWFnZSI6ICJqYXZhIiwKICAgICAgICAgICAgInRhZ3MiOiBbXSwKICAgICAgICAgICAgImFjdGl2ZSI6IHRydWUsCiAgICAgICAgICAgICJ3aGVyZSI6IHsKICAgICAgICAgICAgICAgICJ0eXBlTmFtZSI6ICJjb20uZGF0YWRvZy5UYXJnZXQiLAogICAgICAgICAgICAgICAgIm1ldGhvZE5hbWUiOiAibXlNZXRob2QiLAogICAgICAgICAgICAgICAgInNpZ25hdHVyZSI6ICJqYXZhLmxhbmcuU3RyaW5nICgpIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJtZXRyaWNQcm9iZXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAiaWQiOiAiMzNhNjRkOTktZmJlZC01ZWFiLWJiMTAtODA3MzU0MDVjMDliIiwKICAgICAgICAgICAgInR5cGUiOiAibWV0cmljIiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJraW5kIjogIkNPVU5UIiwKICAgICAgICAgICAgIm1ldHJpY05hbWUiOiAiZGF0YWRvZy5kZWJ1Z2dlci5jYWxscyIsCiAgICAgICAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAgICAgICAgICJleHByIjogIiNsb2NhbFZhcjEuZmllbGQxLmZpZWxkMiIKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIF0sCiAgICAiYWxsb3dMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLmxhbmciCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZy51dGlsLk1hcCIKICAgICAgICBdCiAgICB9LAogICAgImRlbnlMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5IgogICAgICAgIF0sCiAgICAgICAgImNsYXNzZXMiOiBbCiAgICAgICAgICAgICJqYXZheC5zZWN1cml0eS5hdXRoLkF1dGhQZXJtaXNzaW9uIgogICAgICAgIF0KICAgIH0sCiAgICAic2FtcGxpbmciOiB7CiAgICAgICAgInNuYXBzaG90c1BlclNlY29uZCI6IDEuMAogICAgfQp9Cg==" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1tb2RpZmllZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/config" - ] - }, - { - "targets": "eyJzaWduZWQiOnsiX3R5cGUiOiJ0YXJnZXRzIiwiY3VzdG9tIjp7Im9wYXF1ZV9iYWNrZW5kX3N0YXRlIjoiZXlKbWIyOGlPaUFpWW1GeUluMD0ifSwiZXhwaXJlcyI6IjMwMDAtMDEtMDFUMDA6MDA6MDBaIiwic3BlY192ZXJzaW9uIjoiMS4wIiwidGFyZ2V0cyI6eyJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctYmFzZS9jb25maWciOnsiY3VzdG9tIjp7InYiOjJ9LCJoYXNoZXMiOnsic2hhMjU2IjoiOTU4NmY0MjA3ZWQ4ZWYyOTAyODA4MmNiMmJiMmQ3MGZhYTFjNGRkMmU4OTBiMjYwZDBjNjhiMjc1ZjY1YTdjMCJ9LCJsZW5ndGgiOjE1MDN9LCJkYXRhZG9nLzIvTElWRV9ERUJVR0dJTkcvTElWRV9ERUJVR0dJTkctc2Vjb25kL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiJiYWFkMDllYTBhZDY0NDVmNzVjNTFjNTlmZTEzYzA4ZTAxNTcxYzE3MTY0ZDM1MzZkZTU0MGYxYTUxZmNhY2ZjIn0sImxlbmd0aCI6MTUwMX0sImRhdGFkb2cvMi9MSVZFX0RFQlVHR0lORy9MSVZFX0RFQlVHR0lORy10aGlyZC90ZXN0bmFtZSI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiI4NTBkZGFjNzEyZDYxNTM2ZDM5NmZlOWE1MGYwZDYzMzllODMwZDc4MzI2MmUwMTcyZmU5OTA5NTc4MTlhNjNjIn0sImxlbmd0aCI6MTUwMH0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnL2NvbmZpZyI6eyJjdXN0b20iOnsidiI6MX0sImhhc2hlcyI6eyJzaGEyNTYiOiI0NTliZDZhNDAzZDhkNTA5YzQ0M2Q3YjQ2NTVkMDI3YWRhM2NhZGUzM2U4YTM5ZjBkNTQ3ZDAyZjRkYjJkM2Q1In0sImxlbmd0aCI6OH0sImRhdGFkb2cvMi9ST0dVRV9QUk9EVUNUL215Y29uZmlnMi9jb25maWciOnsiY3VzdG9tIjp7InYiOjF9LCJoYXNoZXMiOnsic2hhMjU2IjoiYWZlZjkzNDJlNTZmNDQ2NTJhM2E5YWNkZjRiZGZlZGZlOGRhYjJlMDQ5Nzg4NzM0MTRmNjQzOTU0NDRmZjU0MSJ9LCJsZW5ndGgiOjEyfX0sInZlcnNpb24iOjEyfSwic2lnbmF0dXJlcyI6W3sia2V5aWQiOiJlZDc2NzJjOWEyNGFiZGE3ODg3MmVlMzJlZTcxYzdjYjFkNTIzNWU4ZGI0ZWNiZjFjYTI4YjljNTBlYjc1ZDllIiwic2lnIjoiZTY3NWVjY2Y1YTJjOGZiOWI5Mjc5ZjQ5YWI1YTA1NGJmMzEwYjM5MGY4ODA4OGY1Y2RkNDFiZTM3ZjhhYzUyZDhhYmNhYzRmYWUyNjY0NDRiMDNiMjRmNzljYTM1ZGJkYWNiMzZlNGI3MDI0ODRmYWI5YWMzOTNlZmMxYTk5MGIifV19", - "target_files": [ - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/testname", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy10aGlyZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1zZWNvbmQiLAogICAgIm9yZ0lkIjogMiwKICAgICJzbmFwc2hvdFByb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIyMjk1M2M4OC1lYWRjLTRmOWEtYWEwZi03ZjYyNDNmNGJmOGEiLAogICAgICAgICAgICAidHlwZSI6ICJzbmFwc2hvdCIsCiAgICAgICAgICAgICJjcmVhdGVkIjogMTYwNTA5MzA3MS4wMDAwMDAwMDAsCiAgICAgICAgICAgICJsYW5ndWFnZSI6ICJqYXZhIiwKICAgICAgICAgICAgInRhZ3MiOiBbXSwKICAgICAgICAgICAgImFjdGl2ZSI6IHRydWUsCiAgICAgICAgICAgICJ3aGVyZSI6IHsKICAgICAgICAgICAgICAgICJ0eXBlTmFtZSI6ICJjb20uZGF0YWRvZy5UYXJnZXQiLAogICAgICAgICAgICAgICAgIm1ldGhvZE5hbWUiOiAibXlNZXRob2QiLAogICAgICAgICAgICAgICAgInNpZ25hdHVyZSI6ICJqYXZhLmxhbmcuU3RyaW5nICgpIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJtZXRyaWNQcm9iZXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAiaWQiOiAiMzNhNjRkOTktZmJlZC01ZWFiLWJiMTAtODA3MzU0MDVjMDliIiwKICAgICAgICAgICAgInR5cGUiOiAibWV0cmljIiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJraW5kIjogIkNPVU5UIiwKICAgICAgICAgICAgIm1ldHJpY05hbWUiOiAiZGF0YWRvZy5kZWJ1Z2dlci5jYWxscyIsCiAgICAgICAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAgICAgICAgICJleHByIjogIiNsb2NhbFZhcjEuZmllbGQxLmZpZWxkMiIKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIF0sCiAgICAiYWxsb3dMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLmxhbmciCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZy51dGlsLk1hcCIKICAgICAgICBdCiAgICB9LAogICAgImRlbnlMaXN0IjogewogICAgICAgICJwYWNrYWdlUHJlZml4ZXMiOiBbCiAgICAgICAgICAgICJqYXZhLnNlY3VyaXR5IgogICAgICAgIF0sCiAgICAgICAgImNsYXNzZXMiOiBbCiAgICAgICAgICAgICJqYXZheC5zZWN1cml0eS5hdXRoLkF1dGhQZXJtaXNzaW9uIgogICAgICAgIF0KICAgIH0sCiAgICAic2FtcGxpbmciOiB7CiAgICAgICAgInNuYXBzaG90c1BlclNlY29uZCI6IDEuMAogICAgfQp9Cg==" - }, - { - "path": "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "raw": "ewogICAgImlkIjogInBldGNsaW5pYy1tb2RpZmllZCIsCiAgICAib3JnSWQiOiAyLAogICAgInNuYXBzaG90UHJvYmVzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImlkIjogIjIyOTUzYzg4LWVhZGMtNGY5YS1hYTBmLTdmNjI0M2Y0YmY4YSIsCiAgICAgICAgICAgICJ0eXBlIjogInNuYXBzaG90IiwKICAgICAgICAgICAgImNyZWF0ZWQiOiAxNjA1MDkzMDcxLjAwMDAwMDAwMCwKICAgICAgICAgICAgImxhbmd1YWdlIjogImphdmEiLAogICAgICAgICAgICAidGFncyI6IFtdLAogICAgICAgICAgICAiYWN0aXZlIjogdHJ1ZSwKICAgICAgICAgICAgIndoZXJlIjogewogICAgICAgICAgICAgICAgInR5cGVOYW1lIjogImNvbS5kYXRhZG9nLlRhcmdldCIsCiAgICAgICAgICAgICAgICAibWV0aG9kTmFtZSI6ICJteU1ldGhvZCIsCiAgICAgICAgICAgICAgICAic2lnbmF0dXJlIjogImphdmEubGFuZy5TdHJpbmcgKCkiCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdLAogICAgIm1ldHJpY1Byb2JlcyI6IFsKICAgICAgICB7CiAgICAgICAgICAgICJpZCI6ICIzM2E2NGQ5OS1mYmVkLTVlYWItYmIxMC04MDczNTQwNWMwOWIiLAogICAgICAgICAgICAidHlwZSI6ICJtZXRyaWMiLAogICAgICAgICAgICAiY3JlYXRlZCI6IDE2MDUwOTMwNzEuMDAwMDAwMDAwLAogICAgICAgICAgICAibGFuZ3VhZ2UiOiAiamF2YSIsCiAgICAgICAgICAgICJ0YWdzIjogW10sCiAgICAgICAgICAgICJhY3RpdmUiOiB0cnVlLAogICAgICAgICAgICAid2hlcmUiOiB7CiAgICAgICAgICAgICAgICAidHlwZU5hbWUiOiAiY29tLmRhdGFkb2cuVGFyZ2V0IiwKICAgICAgICAgICAgICAgICJtZXRob2ROYW1lIjogIm15TWV0aG9kIiwKICAgICAgICAgICAgICAgICJzaWduYXR1cmUiOiAiamF2YS5sYW5nLlN0cmluZyAoKSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImtpbmQiOiAiQ09VTlQiLAogICAgICAgICAgICAibWV0cmljTmFtZSI6ICJkYXRhZG9nLmRlYnVnZ2VyLmNhbGxzIiwKICAgICAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICAgICAgImV4cHIiOiAiI2xvY2FsVmFyMS5maWVsZDEuZmllbGQyIgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgXSwKICAgICJhbGxvd0xpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEubGFuZyIKICAgICAgICBdLAogICAgICAgICJjbGFzc2VzIjogWwogICAgICAgICAgICAiamF2YS5sYW5nLnV0aWwuTWFwIgogICAgICAgIF0KICAgIH0sCiAgICAiZGVueUxpc3QiOiB7CiAgICAgICAgInBhY2thZ2VQcmVmaXhlcyI6IFsKICAgICAgICAgICAgImphdmEuc2VjdXJpdHkiCiAgICAgICAgXSwKICAgICAgICAiY2xhc3NlcyI6IFsKICAgICAgICAgICAgImphdmF4LnNlY3VyaXR5LmF1dGguQXV0aFBlcm1pc3Npb24iCiAgICAgICAgXQogICAgfSwKICAgICJzYW1wbGluZyI6IHsKICAgICAgICAic25hcHNob3RzUGVyU2Vjb25kIjogMS4wCiAgICB9Cn0K" - } - ], - "client_configs": [ - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-base/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-second/config", - "datadog/2/LIVE_DEBUGGING/LIVE_DEBUGGING-third/testname" - ] - }, - {} -] diff --git a/utils/scripts/compute-workflow-parameters.py b/utils/scripts/compute-workflow-parameters.py new file mode 100644 index 00000000000..eac57566898 --- /dev/null +++ b/utils/scripts/compute-workflow-parameters.py @@ -0,0 +1,146 @@ +import argparse +import json +import os +from utils._context._scenarios import get_all_scenarios, ScenarioGroup + + +def get_github_workflow_map(scenarios, scenarios_groups): + result = {} + + scenarios_groups = [group.strip() for group in scenarios_groups if group.strip()] + scenarios = {scenario.strip(): False for scenario in scenarios if scenario.strip()} + + for group in scenarios_groups: + try: + ScenarioGroup(group) + except ValueError as e: + raise ValueError(f"Valid groups are: {[item.value for item in ScenarioGroup]}") from e + + for scenario in get_all_scenarios(): + if not scenario.github_workflow: + scenarios[scenario.name] = True # won't be executed, but it exists + continue + + if scenario.github_workflow not in result: + result[scenario.github_workflow] = [] + + if scenario.name in scenarios: + result[scenario.github_workflow].append(scenario.name) + scenarios[scenario.name] = True + + for group in scenarios_groups: + if ScenarioGroup(group) in scenario.scenario_groups: + result[scenario.github_workflow].append(scenario.name) + break + + for scenario, found in scenarios.items(): + if not found: + raise ValueError(f"Scenario {scenario} does not exists") + + return result + + +def get_graphql_weblogs(library): + weblogs = { + "cpp": [], + "dotnet": [], + "golang": ["gqlgen", "graph-gophers", "graphql-go"], + "java": [], + "nodejs": ["express4", "uds-express4", "express4-typescript", "express5"], + "php": [], + "python": [], + "ruby": ["graphql23"], + } + + return weblogs[library] + + +def get_endtoend_weblogs(library): + weblogs = { + "cpp": ["nginx"], + "dotnet": ["poc", "uds"], + "golang": ["chi", "echo", "gin", "net-http", "uds-echo"], + "java": [ + "akka-http", + "jersey-grizzly2", + "play", + "ratpack", + "resteasy-netty3", + "spring-boot-jetty", + "spring-boot", + "spring-boot-3-native", + "spring-boot-openliberty", + "spring-boot-wildfly", + "spring-boot-undertow", + "spring-boot-payara", + "vertx3", + "vertx4", + "uds-spring-boot", + ], + "nodejs": ["express4", "uds-express4", "express4-typescript", "express5", "nextjs"], + "php": [ + *[f"apache-mod-{v}" for v in ["7.0", "7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2"]], + *[f"apache-mod-{v}-zts" for v in ["7.0", "7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2"]], + *[f"php-fpm-{v}" for v in ["7.0", "7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2"]], + ], + "python": ["flask-poc", "django-poc", "uwsgi-poc", "uds-flask", "python3.12", "fastapi"], + "ruby": [ + "rack", + "uds-sinatra", + *[f"sinatra{v}" for v in ["14", "20", "21", "22", "30", "31", "32", "40"]], + *[f"rails{v}" for v in ["42", "50", "51", "52", "60", "61", "70", "71", "72", "80"]], + ], + } + + return weblogs[library] + + +def get_opentelemetry_weblogs(library): + weblogs = { + "cpp": [], + "dotnet": [], + "golang": [], + "java": ["spring-boot-otel"], + "nodejs": ["express4-otel"], + "php": [], + "python": ["flask-poc-otel"], + "ruby": [], + } + + return weblogs[library] + + +def main(language: str, scenarios: str, groups: str): + scenario_map = get_github_workflow_map(scenarios.split(","), groups.split(",")) + + for github_workflow, scenario_list in scenario_map.items(): + print(f"{github_workflow}_scenarios={json.dumps(scenario_list)}") + + endtoend_weblogs = get_endtoend_weblogs(language) + print(f"endtoend_weblogs={json.dumps(endtoend_weblogs)}") + + graphql_weblogs = get_graphql_weblogs(language) + print(f"graphql_weblogs={json.dumps(graphql_weblogs)}") + + opentelemetry_weblogs = get_opentelemetry_weblogs(language) + print(f"opentelemetry_weblogs={json.dumps(opentelemetry_weblogs)}") + + _experimental_parametric_job_count = int(os.environ.get("_EXPERIMENTAL_PARAMETRIC_JOB_COUNT", "1")) + print(f"_experimental_parametric_job_matrix={list(range(1, _experimental_parametric_job_count + 1))!s}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(prog="get-github-parameters", description="Get scenarios and weblog to run") + parser.add_argument( + "language", + type=str, + help="One of the supported Datadog languages", + choices=["cpp", "dotnet", "python", "ruby", "golang", "java", "nodejs", "php"], + ) + + parser.add_argument("--scenarios", "-s", type=str, help="Scenarios to run", default="") + parser.add_argument("--groups", "-g", type=str, help="Scenario groups to run", default="") + + args = parser.parse_args() + + main(language=args.language, scenarios=args.scenarios, groups=args.groups) diff --git a/utils/scripts/compute_impacted_scenario.py b/utils/scripts/compute_impacted_scenario.py index de7a94622d2..ba4225bd836 100644 --- a/utils/scripts/compute_impacted_scenario.py +++ b/utils/scripts/compute_impacted_scenario.py @@ -1,54 +1,73 @@ from collections import defaultdict import json import os +import re from manifests.parser.core import load as load_manifests from utils._context._scenarios import ScenarioGroup -def handle_labels(labels: list[str], scenarios_groups: set[str]): - - if "run-all-scenarios" in labels: - scenarios_groups.add(ScenarioGroup.ALL.value) - else: - if "run-integration-scenarios" in labels: - scenarios_groups.add(ScenarioGroup.INTEGRATIONS.value) - if "run-sampling-scenario" in labels: - scenarios_groups.add(ScenarioGroup.SAMPLING.value) - if "run-profiling-scenario" in labels: - scenarios_groups.add(ScenarioGroup.PROFILING.value) - if "run-debugger-scenarios" in labels: - scenarios_groups.add(ScenarioGroup.DEBUGGER.value) - if "run-appsec-scenarios" in labels: - scenarios_groups.add(ScenarioGroup.APPSEC.value) - if "run-open-telemetry-scenarios" in labels: - scenarios_groups.add(ScenarioGroup.OPEN_TELEMETRY.value) - if "run-parametric-scenario" in labels: - scenarios_groups.add(ScenarioGroup.PARAMETRIC.value) - if "run-graphql-scenarios" in labels: - scenarios_groups.add(ScenarioGroup.GRAPHQL.value) - if "run-libinjection-scenarios" in labels: - scenarios_groups.add(ScenarioGroup.LIB_INJECTION.value) +class Result: + def __init__(self) -> None: + self.scenarios = {"DEFAULT"} # always run the default scenario + self.scenarios_groups = set() + + def add_scenario(self, scenario: str): + if scenario == "EndToEndScenario": + self.add_scenario_group(ScenarioGroup.END_TO_END.value) + else: + self.scenarios.add(scenario) + + def add_scenario_group(self, scenario_group: str): + self.scenarios_groups.add(scenario_group) + + def add_scenarios(self, scenarios: set[str]): + for scenario in scenarios: + self.add_scenario(scenario) + + def handle_labels(self, labels: list[str]): + if "run-all-scenarios" in labels: + self.add_scenario_group(ScenarioGroup.ALL.value) + else: + if "run-integration-scenarios" in labels: + self.add_scenario_group(ScenarioGroup.INTEGRATIONS.value) + if "run-sampling-scenario" in labels: + self.add_scenario_group(ScenarioGroup.SAMPLING.value) + if "run-profiling-scenario" in labels: + self.add_scenario_group(ScenarioGroup.PROFILING.value) + if "run-debugger-scenarios" in labels: + self.add_scenario_group(ScenarioGroup.DEBUGGER.value) + if "run-appsec-scenarios" in labels: + self.add_scenario_group(ScenarioGroup.APPSEC.value) + if "run-open-telemetry-scenarios" in labels: + self.add_scenario_group(ScenarioGroup.OPEN_TELEMETRY.value) + if "run-parametric-scenario" in labels: + self.add_scenario_group(ScenarioGroup.PARAMETRIC.value) + if "run-graphql-scenarios" in labels: + self.add_scenario_group(ScenarioGroup.GRAPHQL.value) + if "run-libinjection-scenarios" in labels: + self.add_scenario_group(ScenarioGroup.LIB_INJECTION.value) + if "run-docker-ssi-scenarios" in labels: + self.add_scenario_group(ScenarioGroup.DOCKER_SSI.value) def main(): - scenarios = set(["DEFAULT"]) # always run the default scenario - scenarios_groups = set() + result = Result() event_name = os.environ["GITHUB_EVENT_NAME"] ref = os.environ["GITHUB_REF"] if event_name == "schedule" or ref == "refs/heads/main": - scenarios_groups.add(ScenarioGroup.ALL.value) + result.add_scenario_group(ScenarioGroup.ALL.value) elif event_name == "pull_request": labels = json.loads(os.environ["GITHUB_PULL_REQUEST_LABELS"]) label_names = [label["name"] for label in labels] - handle_labels(label_names, scenarios_groups) + result.handle_labels(label_names) # this file is generated with # ./run.sh MOCK_THE_TEST --collect-only --scenario-report - with open("logs_mock_the_test/scenarios.json", "r", encoding="utf-8") as f: - scenario_map = json.load(f) + with open("logs_mock_the_test/scenarios.json", encoding="utf-8") as f: + scenario_map: dict[str, list[str]] = json.load(f) modified_nodeids = set() @@ -64,56 +83,39 @@ def main(): modified_nodeids.add(nodeid) scenarios_by_files = defaultdict(set) - for nodeid in scenario_map: + for nodeid, scenarios in scenario_map.items(): file = nodeid.split(":", 1)[0] - scenarios_by_files[file].add(scenario_map[nodeid]) + for scenario in scenarios: + scenarios_by_files[file].add(scenario) for modified_nodeid in modified_nodeids: if nodeid.startswith(modified_nodeid): - scenarios.add(scenario_map[nodeid]) + result.add_scenarios(scenarios) break # this file is generated with # git fetch origin ${{ github.event.pull_request.base.sha || github.sha }} # git diff --name-only HEAD ${{ github.event.pull_request.base.sha || github.sha }} >> modified_files.txt - with open("modified_files.txt", "r", encoding="utf-8") as f: - modified_files = [line.strip() for line in f.readlines()] + with open("modified_files.txt", encoding="utf-8") as f: + modified_files = [line.strip() for line in f] for file in modified_files: - if file.startswith(".circleci") or file.startswith(".github") or file.startswith(".vscode"): - # nothing to do ? - pass - - elif file.startswith("binaries/") or file.startswith("docs/"): - # noting to do - pass - - elif file.startswith("lib-injection/"): - scenarios_groups.add(ScenarioGroup.LIB_INJECTION.value) - - elif file.startswith("manifests/"): - # already handled by the manifest comparison - pass - - elif file.startswith("parametric/"): - # Legacy folder - pass - - elif file.startswith("tests/"): - if file == "tests/test_schemas.py": - # this file is tested in all end-to-end scenarios - scenarios_groups.add(ScenarioGroup.END_TO_END.value) - - elif file.endswith("/utils.py") or file.endswith("/conftest.py"): + if file.startswith("tests/"): + if file.startswith("tests/auto_inject"): + # Nothing to do, onboarding test run on gitlab nightly or manually + pass + elif file.endswith(("/utils.py", "/conftest.py", ".json")): # particular use case for modification in tests/ of a file utils.py or conftest.py # in that situation, takes all scenarios executed in tests// + # same for any json file + folder = "/".join(file.split("/")[:-1]) + "/" # python trickery to remove last element for sub_file in scenarios_by_files: if sub_file.startswith(folder): - scenarios.update(scenarios_by_files[sub_file]) + result.add_scenarios(scenarios_by_files[sub_file]) elif file.startswith("utils/"): if file.startswith("utils/interfaces/schemas"): @@ -144,14 +146,100 @@ def main(): pass else: - raise ValueError(f"Unknown file: {file}. Please add it in this file, with the correct scenario group.") + # Map of file patterns -> scenario group: + # + # * The first matching pattern is applied + # * Others are ignored (so order is important) + # * If no pattern matches -> error + files_map = { + ## scenarios specific folder + r"parametric/.*": None, # Legacy folder + r"lib-injection/.*": ScenarioGroup.LIB_INJECTION.value, + ## nothing to do folders + r"manifests/.*": None, # already handled by the manifest comparison + r"docs/.*": None, # nothing to do + r"binaries/.*": None, # nothing to do + r"\.circleci/.*": None, # nothing to do + r"\.vscode/.*": None, # nothing to do + ## .github folder + r"\.github/workflows/run-parametric\.yml": ScenarioGroup.PARAMETRIC.value, + r"\.github/workflows/run-lib-injection\.yml": ScenarioGroup.LIB_INJECTION.value, + r"\.github/workflows/run-docker-ssi\.yml": ScenarioGroup.DOCKER_SSI.value, + r"\.github/workflows/run-graphql\.yml": ScenarioGroup.GRAPHQL.value, + r"\.github/workflows/run-open-telemetry\.yml": ScenarioGroup.OPEN_TELEMETRY.value, + r"\.github/.*": None, # nothing to do?? + ## utils/ folder + r"utils/interfaces/schemas.*": ScenarioGroup.END_TO_END.value, + r"utils/_context/_scenarios/open_telemetry\.py": ScenarioGroup.OPEN_TELEMETRY.value, + r"utils/scripts/compute_impacted_scenario\.py": None, + r"utils/scripts/get-nightly-logs\.py": None, + #### Default scenario + r"utils/_context/_scenarios/default\.py": None, # the default scenario is always executed + #### Onboarding cases + r"utils/onboarding.*": None, + r"utils/virtual_machine.*": None, + r"utils/build/virtual_machine.*": None, + r"utils/_context/_scenarios/auto_injection\.py": None, + r"utils/_context/virtual_machine\.py": None, + #### Parametric case + r"utils/build/docker/\w+/parametric/.*": ScenarioGroup.PARAMETRIC.value, + r"utils/_context/_scenarios/parametric\.py": ScenarioGroup.PARAMETRIC.value, + r"utils/parametric/.*": ScenarioGroup.PARAMETRIC.value, + r"utils/scripts/parametric/.*": ScenarioGroup.PARAMETRIC.value, + #### Integrations case + r"utils/_context/_scenarios/integrations\.py": ScenarioGroup.INTEGRATIONS.value, + #### Docker SSI case + r"utils/docker_ssi/.*": ScenarioGroup.DOCKER_SSI.value, + ### Profiling case + r"utils/_context/_scenarios/profiling\.py": ScenarioGroup.PROFILING.value, + ### IPv6 + r"utils/_context/_scenarios/ipv6\.py": ScenarioGroup.IPV6.value, + ### otel weblog + r"utils/build/docker/nodejs_otel/.*": ScenarioGroup.OPEN_TELEMETRY.value, + ### else, run all + r"utils/.*": ScenarioGroup.ALL.value, + ## few files with no effect + r"\.github/CODEOWNERS": None, + r"\.dockerignore": None, + r"\.gitattributes": None, + r"\.gitignore": None, + r"\.gitlab-ci\.yml": None, + r"\.shellcheck": None, + r"\.shellcheckrc": None, + r"CHANGELOG\.md": None, + r"LICENSE": None, + r"LICENSE-3rdparty\.csv": None, + r"NOTICE": None, + r"Pulumi\.yaml": None, + r"README\.md": None, + r"format\.sh": None, + r"pyproject\.toml": None, + r"scenario_groups\.yml": None, + ## Nix + r".*\.nix": None, + r"flake\.lock": None, + ## few files with lot of effect + r"requirements\.txt": ScenarioGroup.ALL.value, + r"run\.sh": ScenarioGroup.ALL.value, + r"conftest\.py": ScenarioGroup.ALL.value, + } + + for pattern, scenario_group in files_map.items(): + if re.fullmatch(pattern, file): + if scenario_group is not None: + result.add_scenario_group(scenario_group) + break + else: + raise ValueError( + f"Unknown file: {file}. Please add it in this file, with the correct scenario group." + ) # now get known scenarios executed in this file if file in scenarios_by_files: - scenarios.update(scenarios_by_files[file]) + result.add_scenarios(scenarios_by_files[file]) - print("scenarios=" + ",".join(scenarios)) - print("scenarios_groups=" + ",".join(scenarios_groups)) + print("scenarios=" + ",".join(result.scenarios)) + print("scenarios_groups=" + ",".join(result.scenarios_groups)) if __name__ == "__main__": diff --git a/utils/scripts/decode-rc.py b/utils/scripts/decode-rc.py new file mode 100644 index 00000000000..97729275e18 --- /dev/null +++ b/utils/scripts/decode-rc.py @@ -0,0 +1,74 @@ +import base64 +import json +from black import format_str, FileMode +from utils._remote_config import RemoteConfigCommand + + +def from_payload(payload): + targets = json.loads(base64.b64decode(payload["targets"]).decode("utf-8")) + + result = RemoteConfigCommand(version=targets["signed"]["version"], expires=targets["signed"]["expires"]) + + # base64 -> bytes -> json -> dict + configs = {t["path"]: t["raw"] for t in payload.get("target_files", [])} + + assert result.opaque_backend_state == targets["signed"]["custom"]["opaque_backend_state"] + assert result.spec_version == targets["signed"]["spec_version"] + assert result.expires == targets["signed"]["expires"], f"{result.expires} != {targets['signed']['expires']}" + assert result.version == targets["signed"]["version"], f"{result.version} != {targets['signed']['version']}" + # assert result.signatures == targets["signatures"], f"{result.signatures} != {targets['signatures']}" + + for config_name in payload.get("client_configs", []): + target = targets["signed"]["targets"][config_name] + raw_config = configs.get(config_name) + + config = result.add_client_config(config_name, raw_config, target["custom"]["v"]) + + assert ( + config.config_file_version == target["custom"]["v"] + ), f"{config.config_file_version} != {target['custom']['v']}" + assert ( + config.raw_length == target["length"] + ), f"Length mismatch for {config_name}: {len(config.raw_length)} != {target['length']}" + assert ( + config.raw_sha256 == target["hashes"]["sha256"] + ), f"SHA256 mismatch for {config_name}: {config.raw_sha256} != {target['hashes']['sha256']}" + + return result + + +def get_python_code(command: RemoteConfigCommand): + kwargs = {"version": command.version} + if command.expires != RemoteConfigCommand.expires: + kwargs["expires"] = command.expires + + args = ",".join(f"{k}={v!r}" for k, v in kwargs.items()) + + result = f"command = RemoteConfigCommand({args})" + + for config in command.targets: + result += f"\ncommand.add_client_config{config!r}" + + return format_str(result, mode=FileMode(line_length=120)) + + +def main(filename): + with open(filename, encoding="utf-8") as f: + data = json.load(f) + + for item in data: + print("#" * 120) + if item is None: + print("None") + else: + command = from_payload(item) + print(get_python_code(command)) + + # print("-" * 120) + # print(json.dumps(item, indent=2)) + # print("-" * 120) + # print(json.dumps(command.to_payload(deserialized=True), indent=2)) + + +if __name__ == "__main__": + main("utils/proxy/rc_mocked_responses_asm_nocache.json") diff --git a/utils/scripts/extract_appsec_waf_rules.py b/utils/scripts/extract_appsec_waf_rules.py index 3c2d5c63afc..51369435d2f 100644 --- a/utils/scripts/extract_appsec_waf_rules.py +++ b/utils/scripts/extract_appsec_waf_rules.py @@ -6,13 +6,13 @@ import requests -def to_camel_case(input): - return "".join(ele.title() for ele in input.split("_")) +def to_camel_case(str_input): + return "".join(ele.title() for ele in str_input.split("_")) URL = "https://raw.githubusercontent.com/DataDog/appsec-event-rules/main/build/recommended.json" -data = requests.get(URL).json() +data = requests.get(URL, timeout=10).json() version = data["version"] @@ -28,8 +28,8 @@ def to_camel_case(input): except KeyError: print(event) -HEADER = f"""# Unless explicitly stated otherwise all files in this repository are licensed under the the Apache License Version 2.0. -# This product includes software developed at Datadog (https://www.datadoghq.com/). +HEADER = """# Unless explicitly stated otherwise all files in this repository are licensed under the Apache License +# Version 2.0. This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. # Automatic generatiom from: @@ -42,14 +42,14 @@ def to_camel_case(input): for key, rules in result.items(): f.write(f"\n\nclass {key}:\n") for name, rule in rules.items(): - f.write(f" {name} = \"{rule['id']}\" # {rule['name']}\n") + f.write(f" {name} = \"{rule['id']}\" # {rule['name']}\n") # noqa: Q003 (black does not like this) with open("utils/interfaces/_library/appsec_data.py", "w") as f: f.write(HEADER) f.write("\n\nrule_id_to_type = {\n") for key, rules in result.items(): - for name, rule in rules.items(): + for rule in rules.values(): rule_id = rule["id"] f.write(f' "{rule_id}": "{key}",\n') f.write("}\n") diff --git a/utils/scripts/get-change-log.py b/utils/scripts/get-change-log.py index 2fa1c8c6bd3..c4290fc7228 100644 --- a/utils/scripts/get-change-log.py +++ b/utils/scripts/get-change-log.py @@ -21,7 +21,6 @@ print(f"\n\n### {month} ({len(prs)} PR merged)\n") for pr in prs: - pr["merged_at"] = pr["merged_at"][:10] pr["author"] = pr["user"]["login"] print("* {merged_at} [{title}]({html_url}) by @{author}".format(**pr)) diff --git a/utils/scripts/get-image-list.py b/utils/scripts/get-image-list.py new file mode 100644 index 00000000000..39a26a24c33 --- /dev/null +++ b/utils/scripts/get-image-list.py @@ -0,0 +1,34 @@ +import re +import sys +import yaml + +from utils._context._scenarios import get_all_scenarios, DockerScenario +from utils._context.containers import _get_client + + +if __name__ == "__main__": + library = sys.argv[1] + weblog = sys.argv[2] + executed_scenarios = sys.argv[3] + + images = set("") + + existing_tags = [] + for image in _get_client().images.list(): + existing_tags.extend(image.tags) + + for scenario in get_all_scenarios(): + if f'"{scenario.name}"' in executed_scenarios and isinstance(scenario, DockerScenario): + images.update(scenario.get_image_list(library, weblog)) + + # remove images that will be built locally + images = [image for image in images if not image.startswith("system_tests/")] + + # remove images that exists locally (they may not exists in the registry, ex: buddies) + images = [image for image in images if image not in existing_tags] + + images.sort() + + compose_data = {"services": {re.sub(r"[/:\.]", "-", image): {"image": image} for image in images}} + + print(yaml.dump(compose_data, default_flow_style=False)) diff --git a/utils/scripts/get-nightly-logs.py b/utils/scripts/get-nightly-logs.py new file mode 100644 index 00000000000..cc4838a41b7 --- /dev/null +++ b/utils/scripts/get-nightly-logs.py @@ -0,0 +1,115 @@ +import argparse +import logging +import io +import os +import sys +import tarfile +import zipfile + +import requests + + +logging.basicConfig(level=logging.DEBUG, format="%(levelname)-5s %(message)s") + +logging.getLogger("urllib3").setLevel(logging.WARNING) + + +def get_environ(): + environ = {**os.environ} + + try: + with open(".env", encoding="utf-8") as f: + lines = [line.replace("export ", "").strip().split("=") for line in f if line.strip()] + environ = {**environ, **dict(lines)} + except FileNotFoundError: + pass + + return environ + + +def get_json(session: requests.Session, url: str, params=None, timeout: int = 30): + response = session.get(url, params=params, timeout=timeout) + response.raise_for_status() + return response.json() + + +def is_included(params: list[str], artifact_name: str) -> bool: + return all(param in artifact_name for param in params) + + +def get_artifacts(session: requests.Session, repo_slug: str, workflow_file: str, run_id: int | None): + if run_id is None: + data = get_json( + session, + f"https://api.github.com/repos/{repo_slug}/actions/workflows/{workflow_file}/runs?", + params={"per_page": 1}, + ) + workflow_run = data["workflow_runs"][0] + else: + workflow_run = get_json(session, f"https://api.github.com/repos/{repo_slug}/actions/runs/{run_id}") + + logging.info("Getting artifacts for run: %s", workflow_run["html_url"]) + + artifacts = [] + + for page in range(1, 10): + items = get_json(session, workflow_run["artifacts_url"], params={"per_page": 100, "page": page}) + + if len(items["artifacts"]) == 0: + break + + artifacts.extend(items["artifacts"]) + + return artifacts + + +def download_artifact(session: requests.Session, artifact: dict, output_dir: str | None = None): + logging.info("Downloading artifact: %s", artifact["name"]) + response = session.get(artifact["archive_download_url"], timeout=60) + response.raise_for_status() + + logging.info("Extracting artifact: %s", artifact["name"]) + with zipfile.ZipFile(io.BytesIO(response.content)) as z: + z.extractall(output_dir) + + for file in os.listdir(output_dir): + if file.endswith(".tar.gz") and os.path.isfile(os.path.join(output_dir, file)): + with tarfile.open(os.path.join(output_dir, file), "r:gz") as t: + t.extractall(output_dir, filter=lambda tar_info, _: tar_info) + + +def main( + run_id: int | None, + params: list[str], + repo_slug: str = "DataDog/system-tests-dashboard", + workflow_file: str = "nightly.yml", +): + environ = get_environ() + + with requests.Session() as session: + session.headers.update({"Authorization": f"token {environ['GH_TOKEN']}"}) + + artifacts = get_artifacts(session, repo_slug, workflow_file, run_id) + artifacts = [artifact for artifact in artifacts if is_included(params, artifact["name"])] + + if len(artifacts) == 0: + print("No artifacts found") + sys.exit(1) + + if len(artifacts) > 1: + print("Too many artifacts found:") + for artifact in artifacts: + print("", artifact["name"], artifact["archive_download_url"]) + + sys.exit(1) + + download_artifact(session, artifacts[0], "tmp") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(prog="grep-nightly-logs", description="Get logs artifact from nighty jobs") + parser.add_argument("-r", "--run-id", type=int, help="The run id of the nightly job", required=False) + parser.add_argument("params", type=str, nargs="+", help="Keys in artifact name") + args = parser.parse_args() + + main(run_id=args.run_id, params=args.params) diff --git a/utils/scripts/get-scenarios-from-group.py b/utils/scripts/get-scenarios-from-group.py new file mode 100644 index 00000000000..e47a7a94084 --- /dev/null +++ b/utils/scripts/get-scenarios-from-group.py @@ -0,0 +1,27 @@ +import sys + +from utils._context._scenarios import get_all_scenarios, ScenarioGroup + + +def main(group_name: str): + if group_name == "TRACER_ESSENTIAL_SCENARIOS": # legacy + group_name = "essentials" + + group_name = group_name.strip().lower().replace("_", "-") + + if group_name.endswith("-scenarios"): + group_name = group_name[:-10] + + try: + group = ScenarioGroup(group_name) + except ValueError as e: + raise ValueError(f"Valid groups are: {[item.value for item in ScenarioGroup]}") from e + + scenarios = [scenario.name for scenario in get_all_scenarios() if group in scenario.scenario_groups] + scenarios.sort() + + print("\n".join(scenarios)) + + +if __name__ == "__main__": + main(sys.argv[1]) diff --git a/utils/scripts/get-workflow-summary.py b/utils/scripts/get-workflow-summary.py new file mode 100644 index 00000000000..49d31e64e78 --- /dev/null +++ b/utils/scripts/get-workflow-summary.py @@ -0,0 +1,66 @@ +from collections import defaultdict +import os +import sys + +import requests + + +def get_environ(): + environ = {**os.environ} + + try: + with open(".env", encoding="utf-8") as f: + lines = [line.replace("export ", "").strip().split("=") for line in f if line.strip()] + environ = {**environ, **dict(lines)} + except FileNotFoundError: + pass + + return environ + + +def get_jobs(session, repo_slug: str, run_id: int) -> list: + jobs = [] + params = {"per_page": 100, "page": 1} + while True: + response = session.get(f"https://api.github.com/repos/{repo_slug}/actions/runs/{run_id}/jobs", params=params) + response.raise_for_status() + items = response.json()["jobs"] + if len(items) == 0: + break + + jobs += items + params["page"] += 1 + + return jobs + + +def main(repo_slug: str, run_id: int) -> None: + environ = get_environ() + + with requests.Session() as session: + if "GH_TOKEN" in environ: + session.headers["Authorization"] = environ["GH_TOKEN"] + + jobs = get_jobs(session, repo_slug, run_id) + + failing_steps = defaultdict(list) + + for job in jobs: + if job["conclusion"] != "failure": + continue + + for step in job["steps"]: + if step["conclusion"] == "failure": + failing_steps[step["name"]].append((job, step)) + + for step_name, items in failing_steps.items(): + print(f"❌ **Failures for `{step_name}`**\n") + for job, step in sorted(items, key=lambda x: x[0]["name"]): + url = job["html_url"] + print(f"* [{job['name']}]({url}#step:{step['number']})") + + print() + + +if __name__ == "__main__": + main("DataDog/system-tests", sys.argv[1]) diff --git a/utils/scripts/get_github_parameters.py b/utils/scripts/get_github_parameters.py deleted file mode 100644 index 38cfd8f866e..00000000000 --- a/utils/scripts/get_github_parameters.py +++ /dev/null @@ -1,125 +0,0 @@ -import json -import os -from utils._context._scenarios import get_all_scenarios, ScenarioGroup - - -def get_github_workflow_map(scenarios, scenarios_groups): - result = {} - - scenarios_groups = [group.strip() for group in scenarios_groups if group.strip()] - scenarios = [scenario.strip() for scenario in scenarios if scenario.strip()] - - for group in scenarios_groups: - try: - ScenarioGroup(group) - except ValueError as e: - raise ValueError(f"Valid groups are: {[item.value for item in ScenarioGroup]}") from e - - for scenario in get_all_scenarios(): - if not scenario.github_workflow: - continue - - if scenario.github_workflow not in result: - result[scenario.github_workflow] = [] - - if scenario.name in scenarios: - result[scenario.github_workflow].append(scenario.name) - - for group in scenarios_groups: - if ScenarioGroup(group) in scenario.scenario_groups: - result[scenario.github_workflow].append(scenario.name) - break - - return result - - -def get_graphql_weblogs(library): - weblogs = { - "cpp": [], - "dotnet": [], - "golang": ["gqlgen", "graph-gophers", "graphql-go"], - "java": [], - "nodejs": ["express4", "uds-express4", "express4-typescript"], - "php": [], - "python": [], - "ruby": [], - } - - return weblogs[library] - - -def get_endtoend_weblogs(library): - weblogs = { - "cpp": ["nginx"], - "dotnet": ["poc", "uds"], - "golang": ["chi", "echo", "gin", "net-http", "uds-echo"], - "java": [ - "akka-http", - "jersey-grizzly2", - "play", - "ratpack", - "resteasy-netty3", - "spring-boot-jetty", - "spring-boot", - "spring-boot-3-native", - "spring-boot-openliberty", - "spring-boot-wildfly", - "spring-boot-undertow", - "spring-boot-payara", - "vertx3", - "vertx4", - "uds-spring-boot", - ], - "nodejs": ["express4", "uds-express4", "express4-typescript", "nextjs"], - "php": [ - *[f"apache-mod-{v}" for v in ["7.0", "7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2"]], - *[f"apache-mod-{v}-zts" for v in ["7.0", "7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2"]], - *[f"php-fpm-{v}" for v in ["7.0", "7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2"]], - ], - "python": ["flask-poc", "django-poc", "uwsgi-poc", "uds-flask", "python3.12", "fastapi"], - "ruby": [ - "rack", - "uds-sinatra", - *[f"sinatra{v}" for v in ["14", "20", "21", "22", "30", "31", "32", "40"]], - *[f"rails{v}" for v in ["50", "51", "52", "60", "61", "70", "71"]], - ], - } - - return weblogs[library] - - -def get_opentelemetry_weblogs(library): - - weblogs = { - "cpp": [], - "dotnet": [], - "golang": [], - "java": ["spring-boot-otel"], - "nodejs": ["express4-otel"], - "php": [], - "python": ["flask-poc-otel"], - "ruby": [], - } - - return weblogs[library] - - -def main(): - scenario_map = get_github_workflow_map( - os.environ["SCENARIOS"].split(","), os.environ["SCENARIOS_GROUPS"].split(",") - ) - for github_workflow, scnearios in scenario_map.items(): - print(f"{github_workflow}_scenarios={json.dumps(scnearios)}") - - endtoend_weblogs = get_endtoend_weblogs(os.environ["LIBRARY"]) - print(f"endtoend_weblogs={json.dumps(endtoend_weblogs)}") - - graphql_weblogs = get_graphql_weblogs(os.environ["LIBRARY"]) - print(f"graphql_weblogs={json.dumps(graphql_weblogs)}") - - opentelemetry_weblogs = get_opentelemetry_weblogs(os.environ["LIBRARY"]) - print(f"opentelemetry_weblogs={json.dumps(opentelemetry_weblogs)}") - - -if __name__ == "__main__": - main() diff --git a/utils/scripts/grep-nightly-logs.py b/utils/scripts/grep-nightly-logs.py new file mode 100644 index 00000000000..b97a5264d10 --- /dev/null +++ b/utils/scripts/grep-nightly-logs.py @@ -0,0 +1,121 @@ +import argparse +import logging +import os +import re + +import requests + + +logging.basicConfig(level=logging.DEBUG, format="%(levelname)-5s %(message)s") + +logging.getLogger("urllib3").setLevel(logging.WARNING) + + +def get_environ(): + environ = {**os.environ} + + try: + with open(".env", encoding="utf-8") as f: + lines = [line.replace("export ", "").strip().split("=") for line in f if line.strip()] + environ = {**environ, **dict(lines)} + except FileNotFoundError: + pass + + return environ + + +def get_json(url, headers=None, params=None): + response = requests.get(url, headers=headers, params=params, timeout=30) + response.raise_for_status() + return response.json() + + +def main( + language: str, + log_pattern: str, + repo_slug: str = "DataDog/system-tests-dashboard", + workflow_file: str = "nightly.yml", + branch: str = "main", +): + environ = get_environ() + gh_token = environ["GH_TOKEN"] + headers = {"Authorization": f"token {gh_token}"} + + url = f"https://api.github.com/repos/{repo_slug}/actions/workflows/{workflow_file}/runs?" + + params = {"per_page": 100} + + if branch: + params["branch"] = branch + + data = get_json(url, headers=headers, params=params) + workflows = data.get("workflow_runs", []) + + # sort to get the latest + workflows = sorted(workflows, key=lambda w: w["created_at"], reverse=True) + + for workflow in workflows: + workflow_id = workflow["id"] + for attempt in range(1, workflow["run_attempt"] + 1): + workflow_url = f"https://github.com/{repo_slug}/actions/runs/{workflow_id}/attempts/{attempt}" + + logging.info(f"Workflow #{workflow['run_number']}-{attempt} {workflow['created_at']} {workflow_url}") + + jobs_url = f"https://api.github.com/repos/{repo_slug}/actions/runs/{workflow_id}/attempts/{attempt}/jobs" + params = {"per_page": 100, "page": 1} + + jobs = get_json(jobs_url, headers=headers, params=params) + + while len(jobs["jobs"]) < jobs["total_count"]: + params["page"] += 1 + jobs["jobs"] += get_json(jobs_url, headers=headers, params=params)["jobs"] + + for job in jobs["jobs"]: + job_name = job["name"] + if "artifact" in job_name or (language and language not in job_name): + continue + + if job["conclusion"] != "failure": + continue + + job_id = job["id"] + response = requests.get( + f"https://api.github.com/repos/{repo_slug}/actions/jobs/{job_id}/logs", headers=headers, timeout=60 + ) + content = response.content.decode("utf-8") + + steps = re.split(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z ##\[group\]", content) + + for step in steps: + if log_pattern in step: + first_line = step.split("\n", 1)[0] + logging.info( + f" ✅ Found in https://api.github.com/repos/{repo_slug}/actions/jobs/{job_id}/logs" + ) + logging.info(f" Name : {job_name}") + logging.info(f" Step : {first_line}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(prog="grep-nightly-logs", description="Grep into nightly logs to find a pattern") + parser.add_argument( + "--language", + "-l", + type=str, + help="One of the supported Datadog languages", + choices=["cpp", "dotnet", "python", "ruby", "golang", "java", "nodejs", "php"], + ) + parser.add_argument( + "--repo-slug", + "-r", + type=str, + help="repository slug in the format owner/repo", + default="DataDog/system-tests-dashboard", + ) + parser.add_argument( + "--workflow-file", "-w", type=str, help="Yml file name for the nightly workflow", default="nightly.yml" + ) + parser.add_argument("pattern", type=str, help="Exact pattern to search for in the logs") + args = parser.parse_args() + + main(language=args.language, log_pattern=args.pattern, repo_slug=args.repo_slug, workflow_file=args.workflow_file) diff --git a/utils/scripts/junit_report.py b/utils/scripts/junit_report.py index e50bd23bfb9..c2cf51bcd53 100644 --- a/utils/scripts/junit_report.py +++ b/utils/scripts/junit_report.py @@ -12,7 +12,7 @@ def junit_modifyreport(json_report, junit_report_path, junit_properties): """Add extra information to auto generated JUnit xml file""" # Open XML Junit report - junit_report = ET.parse(junit_report_path) + junit_report = ET.parse(junit_report_path) # noqa: S314 # get root element junit_report_root = junit_report.getroot() for test in json_report["tests"]: @@ -28,9 +28,7 @@ def junit_modifyreport(json_report, junit_report_path, junit_properties): skip_reason = test["metadata"]["details"] error_trace = "" - _create_testcase_results( - junit_report_root, classname, testcasename, outcome, skip_reason, error_trace, - ) + _create_testcase_results(junit_report_root, classname, testcasename, outcome, skip_reason, error_trace) for testsuite in junit_report_root.findall("testsuite"): # Test suite name will be the scanario name @@ -47,9 +45,7 @@ def junit_modifyreport(json_report, junit_report_path, junit_properties): junit_report.write(junit_report_path) -def _create_testcase_results( - junit_xml_root, testclass_name, testcase_name, outcome, skip_reason, error_trace, -): +def _create_testcase_results(junit_xml_root, testclass_name, testcase_name, outcome, skip_reason, error_trace): testcase = junit_xml_root.find(f"testsuite/testcase[@classname='{testclass_name}'][@name='{testcase_name}']") if testcase is not None: # Change name att because CI Visibility uses identifier: testsuite+name diff --git a/utils/scripts/load-binary.sh b/utils/scripts/load-binary.sh index ec41215f19b..743f23bb545 100755 --- a/utils/scripts/load-binary.sh +++ b/utils/scripts/load-binary.sh @@ -165,15 +165,9 @@ if [ "$TARGET" = "java" ]; then ../utils/scripts/docker_base_image.sh ghcr.io/datadog/dd-trace-java/dd-trace-java:latest_snapshot . elif [ "$TARGET" = "dotnet" ]; then + assert_version_is_dev rm -rf *.tar.gz - - if [ $VERSION = 'dev' ]; then - ../utils/scripts/docker_base_image.sh ghcr.io/datadog/dd-trace-dotnet/dd-trace-dotnet:latest_snapshot . - elif [ $VERSION = 'prod' ]; then - ../utils/scripts/docker_base_image.sh ghcr.io/datadog/dd-trace-dotnet/dd-trace-dotnet:latest . - else - echo "Don't know how to load version $VERSION for $TARGET" - fi + ../utils/scripts/docker_base_image.sh ghcr.io/datadog/dd-trace-dotnet/dd-trace-dotnet:latest_snapshot . elif [ "$TARGET" = "python" ]; then assert_version_is_dev @@ -203,6 +197,9 @@ elif [ "$TARGET" = "golang" ]; then echo "Using gopkg.in/DataDog/dd-trace-go.v1@main" echo "gopkg.in/DataDog/dd-trace-go.v1@main" > golang-load-from-go-get + echo "Using ghcr.io/datadog/dd-trace-go/service-extensions-callout:dev" + echo "ghcr.io/datadog/dd-trace-go/service-extensions-callout:dev" > golang-service-extensions-callout-image + elif [ "$TARGET" = "cpp" ]; then assert_version_is_dev # get_circleci_artifact "gh/DataDog/dd-opentracing-cpp" "build_test_deploy" "build" "TBD" diff --git a/utils/scripts/markdown_logs.py b/utils/scripts/markdown_logs.py index 73004ed15b6..7352d5324cd 100644 --- a/utils/scripts/markdown_logs.py +++ b/utils/scripts/markdown_logs.py @@ -14,7 +14,8 @@ def main(): for x in os.listdir("."): if x.startswith("logs") and os.path.isfile(f"{x}/report.json"): result[x] = collections.defaultdict(int) - data = json.load(open(f"{x}/report.json", "r")) + with open(f"{x}/report.json") as f: + data = json.load(f) for test in data["tests"]: outcome = "skipped" if test["metadata"]["details"] is not None else test["outcome"] result[x][outcome] += 1 @@ -22,14 +23,14 @@ def main(): table_row("Scenario", *[f"{outcome} {icon}" for outcome, icon in all_outcomes.items()]) table_row(*(["-"] * (len(all_outcomes) + 1))) - for scenario, outcomes in result.items(): - if scenario == "logs": - scenario = "Main scenario" + for folder_name, outcomes in result.items(): + if folder_name == "logs": + scenario_name = "Main scenario" else: # "ab_cd_ef" => "Ab Cd Ef" - scenario = " ".join([s.capitalize() for s in scenario[5:].split("_")]) + scenario_name = " ".join([s.capitalize() for s in folder_name[5:].split("_")]) - table_row(scenario, *[str(outcomes.get(outcome, "")) for outcome in all_outcomes]) + table_row(scenario_name, *[str(outcomes.get(outcome, "")) for outcome in all_outcomes]) if __name__ == "__main__": diff --git a/utils/scripts/merge_gitlab_aws_pipelines.py b/utils/scripts/merge_gitlab_aws_pipelines.py new file mode 100644 index 00000000000..87342c37b91 --- /dev/null +++ b/utils/scripts/merge_gitlab_aws_pipelines.py @@ -0,0 +1,54 @@ +import yaml +import argparse +import os.path + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--input", required=True, type=str, help="gitlab pipeline to merge") + parser.add_argument("--output", required=True, type=str, help="final gitlab pipeline") + + args = parser.parse_args() + with open(args.input) as f: + pipeline = yaml.safe_load(f) + + if os.path.exists(args.output): + # If final file exists, merge the stages and jobs + with open(args.output) as f: + final_pipeline = yaml.safe_load(f) + for stage in pipeline["stages"]: + if stage not in final_pipeline["stages"]: + final_pipeline["stages"].append(stage) + for job in pipeline: + if job not in final_pipeline: + final_pipeline[job] = pipeline[job] + else: + # If final file does not exist, just copy the pipeline + final_pipeline = pipeline + + # Workaround to set cache stage as the last stage + # and split in stages with not more than 100 jobs + set_cache_2 = False + for key in final_pipeline: + if "stage" in final_pipeline[key] and ( + final_pipeline[key]["stage"] == "Cache" or final_pipeline[key]["stage"] == "Cache2" + ): + final_pipeline[key]["stage"] = "Cache2" if set_cache_2 else "Cache" + set_cache_2 = not set_cache_2 + + if "Cache" in final_pipeline["stages"]: + final_pipeline["stages"].remove("Cache") + final_pipeline["stages"].append("Cache") + if "Cache2" in final_pipeline["stages"]: + final_pipeline["stages"].remove("Cache2") + final_pipeline["stages"].append("Cache2") + else: + final_pipeline["stages"].append("Cache2") + + # Write the final pipeline + with open(args.output, "w") as f: + f.write(yaml.dump(final_pipeline, sort_keys=False, default_flow_style=False)) + + +if __name__ == "__main__": + main() diff --git a/utils/scripts/parametric/generate_protos.ps1 b/utils/scripts/parametric/generate_protos.ps1 deleted file mode 100644 index 9675326de7b..00000000000 --- a/utils/scripts/parametric/generate_protos.ps1 +++ /dev/null @@ -1,8 +0,0 @@ -# Generate protobuf Python source files for the testing client. -# This test client is used to make requests to each of the language-specific -# grpc servers. -# Requires protoc to be installed on the host. - -python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. protos/apm_test_client.proto -# FIXME: the codegen doesn't generate the correct import path -Get-ChildItem ".\protos\*.py" | % { (Get-Content $_.FullName) -replace 'from protos','from parametric.protos' | Set-Content $_.FullName } diff --git a/utils/scripts/parametric/generate_protos.sh b/utils/scripts/parametric/generate_protos.sh deleted file mode 100755 index 8d9271d9878..00000000000 --- a/utils/scripts/parametric/generate_protos.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -# Generate protobuf Python source files for the testing client. -# This test client is used to make requests to each of the language-specific -# grpc servers. -# Requires protoc to be installed on the host. - -python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. protos/apm_test_client.proto -# FIXME: the codegen doesn't generate the correct import path -sed -i '' -e 's/from protos/from parametric.protos/g' protos/*.py diff --git a/utils/scripts/parametric/run_reference_http.sh b/utils/scripts/parametric/run_reference_http.sh index 8445f66ec51..044848bf1e7 100755 --- a/utils/scripts/parametric/run_reference_http.sh +++ b/utils/scripts/parametric/run_reference_http.sh @@ -6,6 +6,9 @@ PORT="${PORT:=8000}" source "$PWD/venv/bin/activate" -pushd "$PWD/utils/build/docker/python_http/parametric" || exit +pip install -r utils/build/docker/python/parametric/requirements.txt +pip install ddtrace + +pushd "$PWD/utils/build/docker/python/parametric" || exit APM_TEST_CLIENT_SERVER_PORT=$PORT python -m apm_test_client popd || exit diff --git a/utils/scripts/push-metrics.py b/utils/scripts/push-metrics.py index 6fd5482468a..441c54a5ee2 100644 --- a/utils/scripts/push-metrics.py +++ b/utils/scripts/push-metrics.py @@ -1,6 +1,6 @@ # Successfully installed datadog_api_client-2.24.1 -from datetime import datetime, timezone +from datetime import datetime, UTC import requests @@ -28,16 +28,13 @@ def main(): data = requests.get("https://dd-feature-parity.azurewebsites.net/statistics", timeout=10) values = flatten(data.json()) - series = [ - Series(metric=name, points=[Point([(datetime.now(timezone.utc)).timestamp(), value]),],) - for name, value in values - ] + series = [Series(metric=name, points=[Point([(datetime.now(UTC)).timestamp(), value])]) for name, value in values] configuration = Configuration(host="datad0g.com") with ApiClient(configuration) as api_client: api_instance = MetricsApi(api_client) response = api_instance.submit_metrics( - content_encoding=MetricContentEncoding.DEFLATE, body=MetricsPayload(series=series), + content_encoding=MetricContentEncoding.DEFLATE, body=MetricsPayload(series=series) ) print(response) diff --git a/utils/scripts/replay_scenarios.sh b/utils/scripts/replay_scenarios.sh index 34d2b47d76b..1d8f6806b37 100755 --- a/utils/scripts/replay_scenarios.sh +++ b/utils/scripts/replay_scenarios.sh @@ -1,10 +1,10 @@ #!/bin/bash -NOT_SUPPPORTED=("K8S_LIB_INJECTION_BASIC" "K8S_LIB_INJECTION_FULL" "TRACE_PROPAGATION_STYLE_W3C" "APM_TRACING_E2E_OTEL" "CROSSED_TRACING_LIBRARIES") +set -e -#if test -f "logs/tests.log"; then -# sh run.sh DEFAULT --replay -#fi + +# scenario getting backedn data are not yet supported +NOT_SUPPPORTED=("APM_TRACING_E2E_OTEL" "PARAMETRIC") if [ -d "logs/" ]; then echo "[DEFAULT] Running replay mode" diff --git a/utils/scripts/update_features.py b/utils/scripts/update_features.py deleted file mode 100644 index 266ce5746a5..00000000000 --- a/utils/scripts/update_features.py +++ /dev/null @@ -1,57 +0,0 @@ -import requests - -from utils import features - - -def get_known_features(): - """ return an object feature_id -> attribute name in features decorator """ - result = {} - - for attr in dir(features): - if attr.startswith("__"): - continue - - def obj(): - pass - - try: - obj = getattr(features, attr)(obj) - except AttributeError: - pass - - if hasattr(obj, "pytestmark"): - result[obj.pytestmark[0].kwargs["feature_id"]] = attr - - return result - - -def _main(): - known_features = get_known_features() - data = requests.get("https://dd-feature-parity.azurewebsites.net/Import/Features", timeout=10).json() - data = {feature["id"]: feature for feature in data} - - for feature_id, python_name in known_features.items(): - if feature_id not in data: - print(f"Feature {python_name}/{feature_id} is not present anymore in the feature parity database") - - for feature in data.values(): - feature_id = feature["id"] - if feature_id not in known_features: - docstring = f""" - {feature['name']} - - https://feature-parity.us1.prod.dog/#/?feature={feature_id}""" - print( - f""" - @staticmethod - def {feature['codeSafeName'].lower()}(test_object): - ""\"{docstring} - ""\" - pytest.mark.features(feature_id={feature_id})(test_object) - return test_object -""" - ) - - -if __name__ == "__main__": - _main() diff --git a/utils/telemetry_utils.py b/utils/telemetry_utils.py new file mode 100644 index 00000000000..3912b852927 --- /dev/null +++ b/utils/telemetry_utils.py @@ -0,0 +1,23 @@ +class TelemetryUtils: + test_loaded_dependencies = { + "dotnet": {"NodaTime": False}, + "nodejs": {"glob": False}, + "java": {"org.apache.httpcomponents:httpclient": False}, + "ruby": {"bundler": False}, + "python": {"requests": False}, + } + + @staticmethod + def get_loaded_dependency(library): + return TelemetryUtils.test_loaded_dependencies[library] + + @staticmethod + def get_dd_appsec_sca_enabled_str(library): + result = "DD_APPSEC_SCA_ENABLED" + if library == "java": + result = "appsec_sca_enabled" + elif library == "nodejs": + result = "appsec.sca.enabled" + elif library in ("php", "ruby"): + result = "appsec.sca_enabled" + return result diff --git a/utils/tools.py b/utils/tools.py index ef40df3a89d..195f5f3242b 100644 --- a/utils/tools.py +++ b/utils/tools.py @@ -2,13 +2,16 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2021 Datadog, Inc. +from enum import StrEnum import logging import os import re import sys +import socket +import random -class bcolors: +class ShColors(StrEnum): CYAN = "\033[96m" MAGENTA = "\033[95m" BLUE = "\033[94m" @@ -27,13 +30,12 @@ def get_log_formatter(): def update_environ_with_local_env(): - # dynamically load .env file in environ if exists, it allow users to keep their conf via env vars try: - with open(".env", "r", encoding="utf-8") as f: + with open(".env", encoding="utf-8") as f: logger.debug("Found a .env file") - for line in f: - line = line.strip(" \t\n") + for raw_line in f: + line = raw_line.strip(" \t\n") line = re.sub(r"(.*)#.$", r"\1", line) line = re.sub(r"^(export +)(.*)$", r"\2", line) if "=" in line: @@ -51,7 +53,6 @@ def update_environ_with_local_env(): def stdout(self, message, *args, **kws): - if self.isEnabledFor(DEBUG_LEVEL_STDOUT): # Yes, logger takes its '*args' as 'args'. self._log(DEBUG_LEVEL_STDOUT, message, args, **kws) # pylint: disable=protected-access @@ -59,14 +60,21 @@ def stdout(self, message, *args, **kws): if hasattr(self, "terminal"): self.terminal.write_line(message) self.terminal.flush() + else: + # at this point, the logger may not yet be configured with the pytest terminal + # so directly print in stdout + print(message) # noqa: T201 logging.Logger.stdout = stdout -def get_logger(name="tests", use_stdout=False): +def get_logger(name="tests", *, use_stdout=False): result = logging.getLogger(name) + logging.getLogger("requests").setLevel(logging.WARNING) + logging.getLogger("urllib3").setLevel(logging.WARNING) + if use_stdout: stdout_handler = logging.StreamHandler(sys.stdout) stdout_handler.setLevel(logging.DEBUG) @@ -79,19 +87,19 @@ def get_logger(name="tests", use_stdout=False): def o(message): - return f"{bcolors.OKGREEN}{message}{bcolors.ENDC}" + return f"{ShColors.OKGREEN}{message}{ShColors.ENDC}" def w(message): - return f"{bcolors.YELLOW}{message}{bcolors.ENDC}" + return f"{ShColors.YELLOW}{message}{ShColors.ENDC}" def m(message): - return f"{bcolors.BLUE}{message}{bcolors.ENDC}" + return f"{ShColors.BLUE}{message}{ShColors.ENDC}" def e(message): - return f"{bcolors.RED}{message}{bcolors.ENDC}" + return f"{ShColors.RED}{message}{ShColors.ENDC}" logger = get_logger() @@ -101,12 +109,11 @@ def get_rid_from_request(request): if request is None: return None - user_agent = [v for k, v in request.request.headers.items() if k.lower() == "user-agent"][0] + user_agent = next(v for k, v in request.request.headers.items() if k.lower() == "user-agent") return user_agent[-36:] def get_rid_from_span(span): - if not isinstance(span, dict): logger.error(f"Span should be an object, not {type(span)}") return None @@ -155,8 +162,8 @@ def get_rid_from_user_agent(user_agent): return match.group(1) -def nested_lookup(needle: str, heystack, look_in_keys=False, exact_match=False): - """ look for needle in heystack, heystack can be a dict or an array """ +def nested_lookup(needle: str, heystack, *, look_in_keys=False, exact_match=False): + """Look for needle in heystack, heystack can be a dict or an array""" if isinstance(heystack, str): return (needle == heystack) if exact_match else (needle in heystack) @@ -182,3 +189,17 @@ def nested_lookup(needle: str, heystack, look_in_keys=False, exact_match=False): return False raise TypeError(f"Can't handle type {type(heystack)}") + + +def get_free_port(): + last_allowed_port = 32000 + port = random.randint(1100, last_allowed_port - 600) + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + while port <= last_allowed_port: + try: + sock.bind(("", port)) + sock.close() + return port + except OSError: + port += 1 + raise OSError("no free ports") diff --git a/utils/virtual_machine/__init__.py b/utils/virtual_machine/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/utils/virtual_machine/aws_provider.py b/utils/virtual_machine/aws_provider.py index a92f3af9fc2..68801e5e3e9 100644 --- a/utils/virtual_machine/aws_provider.py +++ b/utils/virtual_machine/aws_provider.py @@ -1,11 +1,14 @@ import os import pathlib import uuid +import time import requests import tempfile from random import randint +from retry import retry import paramiko +import random from pulumi import automation as auto import pulumi @@ -29,6 +32,14 @@ def __init__(self): self.datadog_event_sender = DatadogEventSender() self.stack_name = "system-tests_onboarding" + def configure(self, required_vms): + super().configure(required_vms) + # Configure the ssh connection for the VMs + self.pulumi_ssh = PulumiSSH() + self.pulumi_ssh.load(required_vms) + for vm in required_vms: + vm.ssh_config.username = vm.aws_config.user + def stack_up(self): logger.info(f"Starting AWS VMs: {self.vms}") @@ -38,8 +49,16 @@ def pulumi_start_program(): self.pulumi_ssh.load(self.vms) # Debug purposes. How many instances, created by system-tests are running in the AWS account? self._check_running_instances() + # Debug purposes. How many AMI CACHES, created by system-tests are available in the AWS account? + # self._check_available_cached_amis() + logger.info(f"Starting AWS VMs.....") + # First check and configure if there are cached AMIs + self._configure_cached_amis(self.vms) + for vm in self.vms: - logger.info(f"--------- Starting AWS VM: {vm.name} -----------") + logger.info( + f"-- Starting AWS VM: [{vm.name}], ID:[{vm.aws_config.ami_id}], update cache:[{vm.datadog_config.update_cache}], skip cache: [{ vm.datadog_config.skip_cache}] --" + ) self._start_vm(vm) project_name = "system-tests-vms" @@ -65,24 +84,19 @@ def pulumi_start_program(): ) def _start_vm(self, vm): - # Check for cached ami, before starting a new one - ami_id = self._get_cached_ami(vm) - logger.info(f"Cache AMI: {vm.get_cache_name()}") - # Startup VM and prepare connection ec2_server = aws.ec2.Instance( vm.name, instance_type=vm.aws_config.ami_instance_type, vpc_security_group_ids=vm.aws_config.aws_infra_config.vpc_security_group_ids, - subnet_id=vm.aws_config.aws_infra_config.subnet_id, + subnet_id=random.choice(vm.aws_config.aws_infra_config.subnet_id), key_name=self.pulumi_ssh.keypair_name, - ami=vm.aws_config.ami_id if ami_id is None else ami_id, + ami=vm.aws_config.ami_id, tags=self._get_ec2_tags(vm), opts=self.pulumi_ssh.aws_key_resource, - root_block_device={"volume_size": 16}, + root_block_device={"volume_size": vm.aws_config.volume_size}, iam_instance_profile=vm.aws_config.aws_infra_config.iam_instance_profile, ) - # Store the private ip of the vm: store it in the vm object and export it. Log to vm_desc.log Output.all(vm, ec2_server.private_ip).apply(lambda args: args[0].set_ip(args[1])) pulumi.export("privateIp_" + vm.name, ec2_server.private_ip) @@ -99,73 +113,98 @@ def _start_vm(self, vm): dial_error_limit=-1, ) # Install provision on the started server - self.install_provision(vm, ec2_server, server_connection, create_cache=ami_id is None) + self.install_provision(vm, ec2_server, server_connection) def stack_destroy(self): - logger.info(f"Destroying VMs: {self.vms}") - try: - self.stack.destroy(on_output=logger.info, debug=True) - self.datadog_event_sender.sendEventToDatadog( - f"[E2E] Stack {self.stack_name} : success on Pulumi stack destroy", - "", - ["operation:destroy", "result:ok", f"stack:{self.stack_name}"], - ) - except Exception as pulumi_exception: - logger.error("Exception destroying aws provision infraestructure") - logger.exception(pulumi_exception) - self.datadog_event_sender.sendEventToDatadog( - f"[E2E] Stack {self.stack_name} : error on Pulumi stack destroy", - repr(pulumi_exception), - ["operation:destroy", "result:fail", f"stack:{self.stack_name}"], - ) - - def _get_cached_ami(self, vm): - """ Check if there is an AMI for one test. Also check if we are using the env var to force the AMI creation""" - ami_id = None - # Configure name - ami_name = vm.get_cache_name() + "__" + context.scenario.name - - # Check for existing ami - ami_existing = aws.ec2.get_ami_ids( - filters=[aws.ec2.GetAmiIdsFilterArgs(name="name", values=[ami_name + "-*"],)], owners=["self"], - ) - - if len(ami_existing.ids) > 0: - # Latest ami details - ami_recent = aws.ec2.get_ami( - filters=[aws.ec2.GetAmiIdsFilterArgs(name="name", values=[ami_name + "-*"],)], - owners=["self"], - most_recent=True, - ) + if os.getenv("ONBOARDING_KEEP_VMS") is None: + logger.info(f"Destroying VMs: {self.vms}") + try: + self.stack.destroy(on_output=logger.info, debug=True) + self.datadog_event_sender.sendEventToDatadog( + f"[E2E] Stack {self.stack_name} : success on Pulumi stack destroy", + "", + ["operation:destroy", "result:ok", f"stack:{self.stack_name}"], + ) + except Exception as pulumi_exception: + logger.error("Exception destroying aws provision infraestructure") + logger.exception(pulumi_exception) + self.datadog_event_sender.sendEventToDatadog( + f"[E2E] Stack {self.stack_name} : error on Pulumi stack destroy", + repr(pulumi_exception), + ["operation:destroy", "result:fail", f"stack:{self.stack_name}"], + ) + else: logger.info( - f"We found an existing AMI with name {ami_name}: [{ami_recent.id}] and status:[{ami_recent.state}] and expiration: [{ami_recent.deprecation_time}]" + f"Did not destroy VMs as ONBOARDING_KEEP_VMS is set. To destroy them, re-run the test without this env var." ) - # The AMI exists. We don't need to create the AMI again - ami_id = ami_recent.id - if str(ami_recent.state) != "available": - logger.info( - f"We found an existing AMI but we can no use it because the current status is {ami_recent.state}" + def _get_cached_amis(self, vms): + """Get all the cached AMIs for the VMs""" + names_filter_to_check = [] + cached_amis = [] + # Create search filter if vm is not marked as skip_cache or update_cache + for vm in vms: + if not vm.datadog_config.skip_cache and not vm.datadog_config.update_cache: + names_filter_to_check.append(vm.get_cache_name() + "-*") + + # There are vms that should use the cache + if len(names_filter_to_check) > 0: + # Check for existing ami cache for the vms + ami_existing = aws.ec2.get_ami_ids( + filters=[aws.ec2.GetAmiIdsFilterArgs(name="name", values=names_filter_to_check)], owners=["self"] + ) + # We found some cached AMIsm let's check the details: status, expiration, etc + for ami in ami_existing.ids: + # Latest ami details + ami_recent = aws.ec2.get_ami( + filters=[aws.ec2.GetAmiIdsFilterArgs(name="image-id", values=[ami])], + owners=["self"], + most_recent=True, ) - logger.info("We are not going to create a new AMI and we are not going to use it") - ami_id = None - ami_name = None - - # But if we ser env var, created AMI again mandatory (TODO we should destroy previously existing one) - if os.getenv("AMI_UPDATE") is not None: - # TODO Pulumi is not prepared to delete resources. Workaround: Import existing ami to pulumi stack, to be deleted when destroying the stack - # aws.ec2.Ami( ami_existing.name, - # name=ami_existing.name, - # opts=pulumi.ResourceOptions(import_=ami_existing.id)) - logger.info("We found an existing AMI but AMI_UPDATE is set. We are going to update the AMI") - ami_id = None - - else: - logger.info(f"Not found an existing AMI with name {ami_name}") - return ami_id + logger.stdout( + f"We found an existing AMI name:[{ami_recent.name}], ID:[{ami_recent.id}], status:[{ami_recent.state}], expiration:[{ami_recent.deprecation_time}], created:[{ami_recent.creation_date}]" + ) + cached_amis.append(ami_recent) + return cached_amis + + def _configure_cached_amis(self, vms): + """Configure the cached AMIs for the VMs""" + before_time = time.time() + cached_amis = self._get_cached_amis(vms) + for vm in vms: + # We don't want to use cache ami for skip_ami_cache or ami_update + if vm.datadog_config.skip_cache or vm.datadog_config.update_cache: + continue + # Let's search the cached AMI for the VM + cached_ami_found = False + for cached_ami in cached_amis: + # The final name it's the vm.get_cache_name() + "-somethingaddedbyaws" + if vm.name in cached_ami.name: + if str(cached_ami.state) != "available": + logger.stdout( + f"We found an existing cache AMI for vm [{vm.name}] but we can no use it because the current status is {cached_ami.state}" + ) + logger.stdout( + "We are not going to create a new AMI and we are not going to use it (skip cache mode)" + ) + vm.datadog_config.update_cache = False + vm.datadog_config.skip_cache = True + else: + logger.stdout( + f"Setting cached AMI for VM [{vm.name}] from base AMI ID [{vm.aws_config.ami_id}] to cached AMI ID [{cached_ami.id}]" + ) + vm.aws_config.ami_id = cached_ami.id + cached_ami_found = True + break + + # Here we don't find a cached AMI for the VM. Force creation + if not cached_ami_found: + vm.datadog_config.update_cache = True + + logger.info(f"Time cache for AMIs: {time.time() - before_time}") def _get_ec2_tags(self, vm): - """ Build the ec2 tags for the VM """ + """Build the ec2 tags for the VM""" tags = {"Name": vm.name, "CI": "system-tests"} if os.getenv("CI_PROJECT_NAME") is not None: @@ -179,31 +218,68 @@ def _get_ec2_tags(self, vm): logger.info(f"Tags for the VM [{vm.name}]: {tags}") return tags + @retry(delay=10, tries=30) def _check_running_instances(self): - """ Print the instances created by system-tests and still running in the AWS account """ + """Check the number of running instances in the AWS account + if there are more than 500 instances, we will wait until they are destroyed + """ - instances = aws.ec2.get_instances(instance_tags={"CI": "system-tests",}, instance_state_names=["running"]) + ec2_ids = self._print_running_instances() + if len(ec2_ids) > 700: + logger.stdout(f"THERE ARE TOO MANY EC2 INSTANCES RUNNING. Waiting for the instances to be destroyed") + raise Exception("Too many ec2 instances running") + + def _print_running_instances(self): + """Print the instances created by system-tests and still running in the AWS account""" + + instances = aws.ec2.get_instances(instance_tags={"CI": "system-tests"}, instance_state_names=["running"]) logger.info(f"AWS Listing running instances with system-tests tag") for instance_id in instances.ids: - logger.info(f"Instance id: [{instance_id}] status:[running] (created by other execution)") + logger.info(f"- Instance id: [{instance_id}] status:[running] (created by other execution)") logger.info(f"Total tags: {instances.instance_tags}") + return instances.ids + + def _check_available_cached_amis(self): + """Print the AMI Caches availables in the AWS account and created by system-tests""" + try: + logger.info(f"AWS Listing available ami caches with system-tests tag") + ami_existing = aws.ec2.get_ami_ids( + filters=[aws.ec2.GetAmiIdsFilterArgs(name="tag:CI", values=["system-tests"])], owners=["self"] + ) + for ami in ami_existing.ids: + # Latest ami details + ami_recent = aws.ec2.get_ami( + filters=[aws.ec2.GetAmiIdsFilterArgs(name="image-id", values=[ami])], + owners=["self"], + most_recent=True, + ) + logger.info( + f"* name:[{ami_recent.name}], ID:[{ami_recent.id}], status:[{ami_recent.state}], expiration:[{ami_recent.deprecation_time}], created:[{ami_recent.creation_date}]" + ) + except Exception as e: + logger.error(f"Error checking cached AMIs: {e}") + logger.info("No cached AMIs found in the account") class AWSCommander(Commander): def create_cache(self, vm, server, last_task): - """ Create a cache : Create an AMI from the server current status.""" - ami_name = vm.get_cache_name() + "__" + context.scenario.name + """Create a cache : Create an AMI from the server current status.""" + ami_name = vm.get_cache_name() # Ok. All third party software is installed, let's create the ami to reuse it in the future - logger.info(f"Creating AMI with name [{ami_name}] from instance ") + logger.stdout(f"Creating AMI with name [{ami_name}] from instance ") + vm_logger(context.scenario.name, "cache_created").info(f"[{context.scenario.name}] - [{ami_name}]") + # Expiration date for the ami # expiration_date = (datetime.now() + timedelta(seconds=30)).strftime("%Y-%m-%dT%H:%M:%SZ") task_dep = aws.ec2.AmiFromInstance( ami_name, + description=ami_name, # deprecation_time=expiration_date, source_instance_id=server.id, opts=pulumi.ResourceOptions(depends_on=[last_task], retain_on_delete=True), + tags={"CI": "system-tests"}, ) return task_dep @@ -223,19 +299,33 @@ def copy_file(self, id, local_path, remote_path, connection, last_task, vm=None) connection=connection, local_path=local_path, remote_path=remote_path, - opts=pulumi.ResourceOptions(depends_on=[last_task]), + opts=pulumi.ResourceOptions(depends_on=[last_task], retain_on_delete=True), ) return last_task def remote_command( - self, vm, installation_id, remote_command, env, connection, last_task, logger_name=None, output_callback=None + self, + vm, + installation_id, + remote_command, + env, + connection, + last_task, + logger_name=None, + output_callback=None, + populate_env=True, ): + if not populate_env: + ##error: Unable to set 'DD_env'. This only works if your SSH server is configured to accept + logger.debug(f"No populate environment variables for installation id: {installation_id} ") + env = {} + cmd_exec_install = command.remote.Command( f"-{vm.name}-{installation_id}", connection=connection, create=remote_command, environment=env, - opts=pulumi.ResourceOptions(depends_on=[last_task]), + opts=pulumi.ResourceOptions(depends_on=[last_task], retain_on_delete=True), ) if logger_name: cmd_exec_install.stdout.apply( @@ -244,7 +334,7 @@ def remote_command( else: # If there isn't logger name specified, we will use the host/ip name to store all the logs of the # same remote machine in the same log file - header = "*****************************************************************" + header = "\n *****************************************************************" Output.all(vm.name, installation_id, remote_command, cmd_exec_install.stdout).apply( lambda args: vm_logger(context.scenario.name, args[0]).info( f"{header} \n - COMMAND: {args[1]} \n {header} \n {args[2]} \n\n {header} \n COMMAND OUTPUT \n\n {header} \n {args[3]}" @@ -267,13 +357,13 @@ def remote_copy_folders( # construct full file path source = source_folder + "/" + file_name destination = destination_folder + "/" + file_name - logger.debug(f"remote_copy_folders: source:[{source}] and remote destination: [{destination}] ") + # logger.debug(f"remote_copy_folders: source:[{source}] and remote destination: [{destination}] ") if os.path.isfile(source): if not relative_path: destination = os.path.basename(destination) - logger.debug(f"Copy single file: source:[{source}] and remote destination: [{destination}] ") + # logger.debug(f"Copy single file: source:[{source}] and remote destination: [{destination}] ") # Launch copy file command quee_depends_on.insert( 0, @@ -282,7 +372,7 @@ def remote_copy_folders( connection=connection, local_path=source, remote_path=destination, - opts=pulumi.ResourceOptions(depends_on=[quee_depends_on.pop()]), + opts=pulumi.ResourceOptions(depends_on=[quee_depends_on.pop()], retain_on_delete=True), ), ) else: @@ -290,7 +380,7 @@ def remote_copy_folders( if not relative_path: p = pathlib.Path("/" + destination) destination = str(p.relative_to(*p.parts[:2])) - logger.debug(f"Creating remote folder: {destination}") + # logger.debug(f"Creating remote folder: {destination}") quee_depends_on.insert( 0, @@ -298,7 +388,7 @@ def remote_copy_folders( "mkdir-" + destination + "-" + str(uuid.uuid4()) + "-" + command_id, connection=connection, create=f"mkdir -p {destination}", - opts=pulumi.ResourceOptions(depends_on=[quee_depends_on.pop()]), + opts=pulumi.ResourceOptions(depends_on=[quee_depends_on.pop()], retain_on_delete=True), ), ) quee_depends_on.insert( @@ -359,14 +449,13 @@ def _write_pem_file(self, pem_file, content): class DatadogEventSender: - """ Send events to Datadog ddev organization """ + """Send events to Datadog ddev organization""" def __init__(self): self.ddev_api_key = os.getenv("DDEV_API_KEY") self.ci_project_name = os.getenv("CI_PROJECT_NAME") def sendEventToDatadog(self, title, message, tags): - if not self.ddev_api_key: logger.error("Datadog API key not found to send event to ddev organization. Skipping event.") return diff --git a/utils/virtual_machine/krunvm_provider.py b/utils/virtual_machine/krunvm_provider.py index fcee019748f..8a1d698369c 100644 --- a/utils/virtual_machine/krunvm_provider.py +++ b/utils/virtual_machine/krunvm_provider.py @@ -14,9 +14,10 @@ class KrunVmProvider(VmProvider): - """ KrunVmProvider is a provider that uses krunvm to create and manage microVMs - see: https://github.com/containers/krunvm/tree/main - see: https://slp.prose.sh/running-microvms-on-m1 """ + """KrunVmProvider is a provider that uses krunvm to create and manage microVMs + see: https://github.com/containers/krunvm/tree/main + see: https://slp.prose.sh/running-microvms-on-m1 + """ def __init__(self): super().__init__() @@ -26,7 +27,7 @@ def __init__(self): self._microvm_processes = [] def _get_container_name(self, microVM_desc): - """ Discover the container name from the microVM description """ + """Discover the container name from the microVM description""" lines = microVM_desc.split("\n") for line in lines: if "Buildah" in line: @@ -42,10 +43,10 @@ def _image_exists(self, image_name): return True def _get_cached_image(self, vm): - """ Check if there is an image for one test. Also check if we are using the env var to force the iamge creation""" + """Check if there is an image for one test. Also check if we are using the env var to force the iamge creation""" image_id = None # Configure name - image_name = vm.get_cache_name() + "_" + context.scenario.name + image_name = vm.get_cache_name() image_name = image_name.lower() image_id = "localhost/" + image_name @@ -119,7 +120,7 @@ def stack_up(self): logger.info(microvm_process.after) self._microvm_processes.append(microvm_process) - self.install_provision(vm, container_name, None, create_cache=image_id is None) + self.install_provision(vm, container_name, None) # vm.set_ip("localhost"): Krunvm provides a special networking protocol, some apps may not work with it. # Instead of use a network, we can use stdin to lauch commands on the microVM vm.krunvm_config.stdin = self.commander._get_stdin_path(vm) @@ -144,21 +145,22 @@ def stack_destroy(self): class KrunVmCommander(Commander): def _get_shared_folder_path(self, vm): - """ Local shared folder path""" + """Local shared folder path""" return os.path.join(context.scenario.host_log_folder, vm.name, "shared_volume") def _get_stdin_path(self, vm): - """ Local std.in path: we use std.in to execute commands on the microVM. - We write the commands to execute on this file and the output is sent to the stod.out file""" + """Local std.in path: we use std.in to execute commands on the microVM. + We write the commands to execute on this file and the output is sent to the stod.out file + """ return os.path.join(self._get_shared_folder_path(vm), "std.in") def create_cache(self, vm, server, last_task): - """ Create a cache : We execute buildah commit to store currebt state of the microVM as an image""" + """Create a cache : We execute buildah commit to store currebt state of the microVM as an image""" # First we need to wait for cacheable commands to be processed self.wait_until_commands_processed(vm, timeout=600) - cache_image_name = vm.get_cache_name() + "_" + context.scenario.name + cache_image_name = vm.get_cache_name() cache_image_name = cache_image_name.lower() # Ok. All third party software is installed, let's create the ami to reuse it in the future logger.info(f"Creating cached image with name [{cache_image_name}] from [{vm.name}] and container [{server}]") @@ -180,7 +182,16 @@ def copy_file(self, id, local_path, remote_path, connection, last_task, vm=None) shutil.copyfile(local_path, os.path.join(self._get_shared_folder_path(vm), remote_path)) def remote_command( - self, vm, installation_id, remote_command, env, connection, last_task, logger_name=None, output_callback=None + self, + vm, + installation_id, + remote_command, + env, + connection, + last_task, + logger_name=None, + output_callback=None, + populate_env=True, ): # Workaround with env variables :-( export_command = "" diff --git a/utils/virtual_machine/utils.py b/utils/virtual_machine/utils.py new file mode 100644 index 00000000000..5ae42241d44 --- /dev/null +++ b/utils/virtual_machine/utils.py @@ -0,0 +1,277 @@ +import os +import pytest +from utils import context +from utils._decorators import is_jira_ticket +from copy import deepcopy + + +def parametrize_virtual_machines(bugs: list[dict] = None): + """You can set multiple bugs for a single test case. + If you want to set a bug for a specific VM, you can set the vm_name or vm_cpu or weblog_variant in the bug dictionary (using one or more fields). + ie: + - Marks as bug for vm with name "vm1" and weblog_variant "app1" + * @parametrize_virtual_machines(bugs=[{"vm_name":"vm1", "weblog_variant":"app1", "reason": "APMON-1576"}]) + - Marks as bug for vm with cpu type "amd64" and weblog_variant "app1" + * @parametrize_virtual_machines(bugs=[{"vm_cpu":"amd64", "weblog_variant":"app1", "reason": "APMON-1576"}]) + - Marks as bug for all vm with cpu type "amd64" and all weblogs + * @parametrize_virtual_machines(bugs=[{"vm_cpu":"amd64","reason": "APMON-1576"}]) + - Marks as bug for all vms that belong to "debian" and all weblogs + * @parametrize_virtual_machines(bugs=[{"vm_branch":"debian","reason": "APMON-1576"}]) + Reason is mandatory for each bug and it MUST reference to a JIRA ticket. + """ + if callable(bugs): + # here, bugs is not the bug list, but the decorated method + raise TypeError(f"Typo in {bugs}'s decorator, you forgot parenthesis. Please use `@decorator()`") + + def decorator(func): + # We group the parameters/vms. We want to execute in same worker the tests for one machine. We need to control the test order for each machine. + # https://github.com/pytest-dev/pytest-xdist/issues/58 + parameters = [] + count = 0 + + # We need to group the vms by runtime. We can't have multiple weblogs in the same vm (muticontainer apps or multicontainer alpine). + vms_by_runtime, vms_by_runtime_ids = get_tested_apps_vms() + + # Mark the test with bug marker if we need + # Setting groups for xdist + for vm in vms_by_runtime: + bug_found = False + if bugs: + for bug in bugs: + if ( + (not "vm_name" in bug or vm.name == bug["vm_name"]) + and (not "vm_branch" in bug or vm.os_branch == bug["vm_branch"]) + and (not "vm_cpu" in bug or vm.os_cpu == bug["vm_cpu"]) + and (not "weblog_variant" in bug or context.weblog_variant == bug["weblog_variant"]) + and (not "library" in bug or context.library == bug["library"]) + and ( + not "runtime_version" in bug + or vm.get_deployed_weblog().runtime_version == bug["runtime_version"] + ) + ): + if "reason" in bug and is_jira_ticket(bug["reason"]): + parameters.append( + pytest.param( + vm, + marks=[ + pytest.mark.xfail(reason=f"bug: {bug['reason']}"), + pytest.mark.xdist_group(f"group{count}"), + ], + ) + ) + bug_found = True + break + else: + raise ValueError(f"Invalid bug reason for {vm.name} {bug}. Please use a valid JIRA ticket.") + + if bug_found == False: + parameters.append(pytest.param(vm, marks=pytest.mark.xdist_group(f"group{count}"))) + count += 1 + return pytest.mark.parametrize("virtual_machine", parameters, ids=vms_by_runtime_ids)(func) + + return decorator + + +def get_tested_apps_vms(): + """Workaround for multicontainer apps. We are going duplicate the machines for each runtime inside of docker compose. + This means, if I have a multicontainer app with 3 containers (runtimes) running on 1 vm, I will have 3 machines with the same configuration but with different runtimes. + NOTE: On AWS we only run 1 vm. We duplicate the vms for test isolation. + """ + vms_by_runtime = [] + vms_by_runtime_ids = [] + for vm in getattr(context.scenario, "required_vms", []): + deployed_weblog = vm.get_provision().get_deployed_weblog() + if deployed_weblog.app_type == "multicontainer": + for weblog in deployed_weblog.multicontainer_apps: + vm_by_runtime = deepcopy(vm) + vm_by_runtime.set_deployed_weblog(weblog) + vms_by_runtime.append(vm_by_runtime) + vms_by_runtime_ids.append(vm_by_runtime.get_vm_unique_id()) + else: + vms_by_runtime.append(vm) + vms_by_runtime_ids.append(vm.get_vm_unique_id()) + + return vms_by_runtime, vms_by_runtime_ids + + +def nginx_parser(nginx_config_file): + """Parse the nginx config file and return the apps in the return block of the location block of the server block of the http block. + TODO: Improve this uggly code + """ + import crossplane + import json + + nginx_config = crossplane.parse(nginx_config_file) + config_endpoints = nginx_config["config"] + for config_endpoint in config_endpoints: + parsed_data = config_endpoint["parsed"] + for parsed in parsed_data: + if "http" == parsed["directive"]: + parsed_blocks = parsed["block"] + for parsed_block in parsed_blocks: + if "server" in parsed_block["directive"]: + parsed_server_blocks = parsed_block["block"] + for parsed_server_block in parsed_server_blocks: + if "location" in parsed_server_block["directive"] and parsed_server_block["args"][0] == "/": + parsed_server_location_blocks = parsed_server_block["block"] + for parsed_server_location_block in parsed_server_location_blocks: + if "return" in parsed_server_location_block["directive"]: + return_args = parsed_server_location_block["args"] + # convert string to object + json_object = json.loads(return_args[1].replace("'", '"')) + return json_object["apps"] + + +def generate_gitlab_pipeline( + language, + weblog_name, + scenario_name, + env, + vms, + installer_library_version, + installer_injector_version, + is_one_pipeline, +): + pipeline = { + "include": [ + {"remote": "https://gitlab-templates.ddbuild.io/libdatadog/include/single-step-instrumentation-tests.yml"} + ], + "variables": { + "KUBERNETES_SERVICE_ACCOUNT_OVERWRITE": "system-tests", + "TEST": "1", + "KUBERNETES_CPU_REQUEST": "6", + "KUBERNETES_CPU_LIMIT": "6", + }, + "stages": ["dummy"], + # A dummy job is necessary for cases where all of the test jobs are manual + # The child pipeline shows as failed until at least 1 job is run + "dummy": { + "image": "registry.ddbuild.io/docker:20.10.13-gbi-focal", + "tags": ["arch:amd64"], + "stage": "dummy", + "dependencies": [], + "script": ["echo 'DONE'"], + }, + ".base_job_onboarding_system_tests": { + "extends": ".base_job_onboarding", + "after_script": [ + 'SCENARIO_SUFIX=$(echo "$SCENARIO" | tr "[:upper:]" "[:lower:]")', + 'REPORTS_PATH="reports/"', + 'mkdir -p "$REPORTS_PATH"', + 'cp -R logs_"${SCENARIO_SUFIX}" $REPORTS_PATH/', + 'cp logs_"${SCENARIO_SUFIX}"/feature_parity.json "$REPORTS_PATH"/"${SCENARIO_SUFIX}".json', + 'mv "$REPORTS_PATH"/logs_"${SCENARIO_SUFIX}" "$REPORTS_PATH"/logs_"${TEST_LIBRARY}"_"${ONBOARDING_FILTER_WEBLOG}"_"${SCENARIO_SUFIX}_${DEFAULT_VMS}"', + ], + "artifacts": {"when": "always", "paths": ["reports/"]}, + }, + ".base_job_onboarding_one_pipeline": { + "extends": ".base_job_onboarding", + "after_script": [ + "cd system-tests", + 'SCENARIO_SUFIX=$(echo "$SCENARIO" | tr "[:upper:]" "[:lower:]")', + 'REPORTS_PATH="reports/"', + 'mkdir -p "$REPORTS_PATH"', + 'cp -R logs_"${SCENARIO_SUFIX}" $REPORTS_PATH/', + 'cp logs_"${SCENARIO_SUFIX}"/feature_parity.json "$REPORTS_PATH"/"${SCENARIO_SUFIX}".json', + 'mv "$REPORTS_PATH"/logs_"${SCENARIO_SUFIX}" "$REPORTS_PATH"/logs_"${TEST_LIBRARY}"_"${ONBOARDING_FILTER_WEBLOG}"_"${SCENARIO_SUFIX}_${DEFAULT_VMS}"', + ], + "artifacts": {"when": "always", "paths": ["system-tests/reports/"]}, + }, + } + # Add FPD push script + pipeline[".base_job_onboarding_system_tests"]["after_script"].extend(_generate_fpd_gitlab_script()) + + # if we execute the pipeline manually, we want don't want to run the child jobs by default + # if we execute the pipeline by schedule, we want to run the child jobs by default + rule_run = {"if": '$CI_PIPELINE_SOURCE == "schedule"', "when": "always"} + if os.getenv("CI_PIPELINE_SOURCE", "") == "schedule": + rule_run = {"if": '$CI_PIPELINE_SOURCE == "parent_pipeline"', "when": "always"} + + # Generate a job per machine + if vms: + pipeline["stages"].append(scenario_name) + + for vm in vms: + pipeline[f"{vm.name}_{weblog_name}_{scenario_name}"] = { + "extends": ".base_job_onboarding_one_pipeline" + if is_one_pipeline + else ".base_job_onboarding_system_tests", + "stage": scenario_name, + "allow_failure": False, + "needs": [], + "variables": { + "TEST_LIBRARY": language, + "SCENARIO": scenario_name, + "WEBLOG": weblog_name, + "ONBOARDING_FILTER_ENV": env, + "DD_INSTALLER_LIBRARY_VERSION": installer_library_version, + "DD_INSTALLER_INJECTOR_VERSION": installer_injector_version, + }, + # Remove rules if you want to run the jobs when you clic on the execute button of the child pipeline + "rules": [rule_run, {"when": "manual", "allow_failure": True}], + "script": [ + "./build.sh -i runner", + "timeout 3000 ./run.sh $SCENARIO --vm-weblog $WEBLOG --vm-env $ONBOARDING_FILTER_ENV --vm-library $TEST_LIBRARY --vm-provider aws --report-run-url $CI_PIPELINE_URL --report-environment $ONBOARDING_FILTER_ENV --vm-default-vms All --vm-only " + + vm.name, + ], + } + if is_one_pipeline: + # If it's a one pipeline, we need to clone the system-tests repo and the job is going to be executed automatically + pipeline[f"{vm.name}_{weblog_name}_{scenario_name}"]["rules"] = [{"when": "always"}] + pipeline[f"{vm.name}_{weblog_name}_{scenario_name}"]["script"].insert( + 0, "git clone https://git@github.com/DataDog/system-tests.git system-tests" + ) + pipeline[f"{vm.name}_{weblog_name}_{scenario_name}"]["script"].insert(1, "cd system-tests") + + if not is_one_pipeline: + # Cache management for the system-tests pipeline + pipeline["stages"].append("Cache") + pipeline.update(_generate_cache_jobs(language, weblog_name, scenario_name, vms)) + + return pipeline + + +def _generate_cache_jobs(language, weblog_name, scenario_name, vms): + pipeline = {} + # Generate a job per machine + for vm in vms: + pipeline[f"{vm.get_cache_name()}"] = { + "extends": ".base_job_onboarding_system_tests", + "stage": "Cache", + "allow_failure": True, + "needs": [], + "variables": { + "TEST_LIBRARY": language, + "SCENARIO": scenario_name, + "WEBLOG": weblog_name, + "AMI_UPDATE": "true", + }, + # Remove rules if you want to run the jobs when you clic on the execute button of the child pipeline. + "rules": [{"when": "manual", "allow_failure": True}], + "script": [ + "./build.sh -i runner", + "./run.sh $SCENARIO --vm-weblog $WEBLOG --vm-env prod --vm-library $TEST_LIBRARY --vm-provider aws --vm-default-vms All --vm-only " + + vm.name, + ], + } + return pipeline + + +def _generate_fpd_gitlab_script(): + fpd_push_script = [ + 'if [ "$CI_COMMIT_BRANCH" = "main" ]; then', + 'export FP_IMPORT_URL=$(aws ssm get-parameter --region us-east-1 --name ci.system-tests.fp-import-url --with-decryption --query "Parameter.Value" --out text)', + 'export FP_API_KEY=$(aws ssm get-parameter --region us-east-1 --name ci.system-tests.fp-api-key --with-decryption --query "Parameter.Value" --out text)', + "for folder in reports/logs*/ ; do", + ' echo "Checking folder: ${folder}"', + " for filename in ./${folder}*_feature_parity.json; do", + " if [ -e ${filename} ]", + " then", + ' echo "Processing report: ${filename}"', + ' curl -X POST ${FP_IMPORT_URL} --fail --header "Content-Type: application/json" --header "FP_API_KEY: ${FP_API_KEY}" --data "@${filename}" --include', + " fi", + " done", + "done", + "fi", + ] + return fpd_push_script diff --git a/utils/virtual_machine/vagrant_provider.py b/utils/virtual_machine/vagrant_provider.py index 2111072c9c2..9aa5f5cca93 100644 --- a/utils/virtual_machine/vagrant_provider.py +++ b/utils/virtual_machine/vagrant_provider.py @@ -41,8 +41,8 @@ def stack_up(self): self.install_provision(vm, None, client) def _set_vagrant_configuration(self, vm): - """ Makes some configuration on the vagrant files - These configurations are relative to the provider and to port forwarding (for weblog) and port for ssh + """Makes some configuration on the vagrant files + These configurations are relative to the provider and to port forwarding (for weblog) and port for ssh TODO Support for different vagrant providers. Currently only support for qemu """ @@ -58,7 +58,7 @@ def _set_vagrant_configuration(self, vm): qe.machine = "q35" qe.cpu = "max" qe.smp = "cpus=8,sockets=1,cores=8,threads=1" - qe.net_device = "virtio-net-pci" + qe.net_device = "virtio-net-pci" """ port_configuration = f""" config.vm.network "forwarded_port", guest: 5985, host: {vm.deffault_open_port} @@ -101,14 +101,21 @@ def execute_local_command(self, local_command_id, local_command, env, last_task, return last_task def copy_file(self, id, local_path, remote_path, connection, last_task, vm=None): - SCPClient(connection.get_transport()).put(local_path, remote_path) return last_task def remote_command( - self, vm, installation_id, remote_command, env, connection, last_task, logger_name=None, output_callback=None + self, + vm, + installation_id, + remote_command, + env, + connection, + last_task, + logger_name=None, + output_callback=None, + populate_env=True, ): - logger.debug(f"Running remote-command with installation id: {installation_id}") # Workaround with env variables and paramiko :-( @@ -160,9 +167,9 @@ def remote_copy_folders( class MySFTPClient(paramiko.SFTPClient): def put_dir(self, source, target): - """ Uploads the contents of the source directory to the target path. The - target directory needs to exists. All subdirectories in source are - created under target. + """Uploads the contents of the source directory to the target path. The + target directory needs to exists. All subdirectories in source are + created under target. """ for item in os.listdir(source): if os.path.isfile(os.path.join(source, item)): @@ -172,7 +179,7 @@ def put_dir(self, source, target): self.put_dir(os.path.join(source, item), "%s/%s" % (target, item)) def mkdir(self, path, mode=511, ignore_existing=False): - """ Augments mkdir by adding an option to not fail if the folder exists """ + """Augments mkdir by adding an option to not fail if the folder exists""" try: super(MySFTPClient, self).mkdir(path, mode) except IOError: diff --git a/utils/virtual_machine/virtual_machine_provider.py b/utils/virtual_machine/virtual_machine_provider.py index 2b41e5413d1..59a8d78d15f 100644 --- a/utils/virtual_machine/virtual_machine_provider.py +++ b/utils/virtual_machine/virtual_machine_provider.py @@ -4,7 +4,7 @@ class VmProviderFactory: - """ Use the correct provider specified by Id """ + """Use the correct provider specified by Id""" def get_provider(self, provider_id): logger.info(f"Using {provider_id} provider") @@ -25,8 +25,9 @@ def get_provider(self, provider_id): class VmProvider: - """ Provider responsible of manage the virtual machines - Start up all the stack (group of virtual machines) """ + """Provider responsible of manage the virtual machines + Start up all the stack (group of virtual machines) + """ def __init__(self): self.vms = None @@ -38,24 +39,25 @@ def configure(self, required_vms): self.vms = required_vms def stack_up(self): - """ Each provider should implement the method that start up all the machines. - After each machine is up, you will call the install_provision method for each machine. """ + """Each provider should implement the method that start up all the machines. + After each machine is up, you will call the install_provision method for each machine. + """ raise NotImplementedError def stack_destroy(self): - """ Stop and destroy machines""" + """Stop and destroy machines""" raise NotImplementedError - def install_provision(self, vm, server, server_connection, create_cache=True): - """ - This method orchestrate the provision installation for a machine + def install_provision(self, vm, server, server_connection): + """Orchestrate the provision installation for a machine Vm object contains the provision for the machine. The provision structure must satisfy the class utils/virtual_machine/virtual_machine_provisioner.py#Provision - This is a common method for all providers""" + This is a common method for all providers + """ logger.stdout(f"Provisioning [{vm.name}]") provision = vm.get_provision() last_task = server - if create_cache: + if vm.datadog_config.update_cache or vm.datadog_config.skip_cache: # First install cacheable installations for installation in provision.installations: if installation.cache: @@ -66,7 +68,9 @@ def install_provision(self, vm, server, server_connection, create_cache=True): if provision.lang_variant_installation: logger.stdout(f"[{vm.name}] Provisioning lang variant {provision.lang_variant_installation.id}") last_task = self._remote_install(server_connection, vm, last_task, provision.lang_variant_installation) - last_task = self.commander.create_cache(vm, server, last_task) + + if vm.datadog_config.update_cache and not vm.datadog_config.skip_cache: + last_task = self.commander.create_cache(vm, server, last_task) # Then install non cacheable installations for installation in provision.installations: @@ -77,8 +81,9 @@ def install_provision(self, vm, server, server_connection, create_cache=True): # Extract tested/installed components logger.stdout(f"[{vm.name}] Extracting {provision.tested_components_installation.id}") + # We don't get the last_task. This task can be executed in parallel with the next one output_callback = lambda args: args[0].set_tested_components(args[1]) - last_task = self._remote_install( + self._remote_install( server_connection, vm, last_task, @@ -86,14 +91,47 @@ def install_provision(self, vm, server, server_connection, create_cache=True): logger_name="tested_components", output_callback=output_callback, ) + # Before install weblog, if we set the env variable: GITLAB_CI, we need to checkout the CI_COMMIT_BRANCH branch + # (we are going to copy weblog sources from git instead from local machine) + # We commit the branch reference of the CI_COMMIT_BRANCH env variable only if the gitlab project is system-tests + # Proabably we need to change this in the future, and translate this logic to the pipelines or another class + ci_commit_branch = os.getenv("GITLAB_CI") + if ci_commit_branch: + ci_commit_branch = ( + os.getenv("CI_COMMIT_BRANCH") if os.getenv("CI_PROJECT_NAME", "") == "system-tests" else "main" + ) + logger.stdout(f"[{vm.name}] Checkout branch {ci_commit_branch}") + last_task = self.commander.remote_command( + vm, + "checkout_branch", + f"cd system-tests && git reset --hard HEAD && git pull && git checkout {ci_commit_branch}", + vm.get_command_environment(), + server_connection, + last_task, + ) # Finally install weblog logger.stdout(f"[{vm.name}] Installing {provision.weblog_installation.id}") last_task = self._remote_install(server_connection, vm, last_task, provision.weblog_installation) + # Extract logs + if provision.vm_logs_installation: + logger.stdout(f"[{vm.name}] Extracting logs {provision.vm_logs_installation.id}") + + output_callback = lambda args: args[0].set_vm_logs(args[1]) + last_task = self._remote_install( + server_connection, + vm, + last_task, + provision.vm_logs_installation, + logger_name=f"{vm.name}_var_log", + output_callback=output_callback, + ) + def _remote_install(self, server_connection, vm, last_task, installation, logger_name=None, output_callback=None): - """ Manages a installation. - The installation must satisfy the class utils/virtual_machine/virtual_machine_provisioner.py#Installation """ + """Manages a installation. + The installation must satisfy the class utils/virtual_machine/virtual_machine_provisioner.py#Installation + """ local_command = None command_environment = vm.get_command_environment() # Execute local command if we need @@ -112,20 +150,39 @@ def _remote_install(self, server_connection, vm, last_task, installation, logger # Copy files from local to remote if we need if installation.copy_files: for file_to_copy in installation.copy_files: - # If we don't use remote_path, the remote_path will be a default remote user home if file_to_copy.remote_path: remote_path = file_to_copy.remote_path + elif file_to_copy.git_path: + remote_path = "." else: remote_path = os.path.basename(file_to_copy.local_path) - if not os.path.isdir(file_to_copy.local_path): + if file_to_copy.git_path: + logger.debug("Copy file from git path") + + if os.path.isdir(file_to_copy.git_path): + file_to_copy.git_path = file_to_copy.git_path + "/*" + + # system-tests is cloned into home folder + last_task = self.commander.remote_command( + vm, + file_to_copy.name + f"-{vm.name}-{installation.id}", + "cp -r system-tests/" + file_to_copy.git_path + " " + remote_path, + command_environment, + server_connection, + last_task, + logger_name=logger_name, + output_callback=output_callback, + populate_env=installation.populate_env, + ) + elif not os.path.isdir(file_to_copy.local_path): # If the local path contains a variable, we need to replace it for key, value in command_environment.items(): file_to_copy.local_path = file_to_copy.local_path.replace(f"${key}", value) remote_path = remote_path.replace(f"${key}", value) - logger.debug(f"Copy file from {file_to_copy.local_path} to {remote_path}") + # logger.debug(f"Copy file from {file_to_copy.local_path} to {remote_path}") # Launch copy file command last_task = self.commander.copy_file( file_to_copy.name + f"-{vm.name}-{installation.id}", @@ -155,47 +212,55 @@ def _remote_install(self, server_connection, vm, last_task, installation, logger last_task, logger_name=logger_name, output_callback=output_callback, + populate_env=installation.populate_env, ) class Commander: - """ Run commands on the VMs. Each provider should implement this class.""" + """Run commands on the VMs. Each provider should implement this class.""" def create_cache(self, vm, server, last_task): - """ Create a cache from existing server. - Use vm.get_cache_name() to get the cache name. - Server is the started server to create the cache from. - Use last_task to depend on the last executed task. - Return the current task executed.""" + """Create a cache from existing server. + Use vm.get_cache_name() to get the cache name. + Server is the started server to create the cache from. + Use last_task to depend on the last executed task. + Return the current task executed. + """ return last_task def execute_local_command(self, local_command_id, local_command, env, last_task, logger_name): - """ Execute a local command in the current machine. - Env contain environment variables to be used in the command. - logger_name is the name of the logger to use to store the output of the command. - Use last_task to depend on the last executed task. - Return the current task executed.""" + """Execute a local command in the current machine. + Env contain environment variables to be used in the command. + logger_name is the name of the logger to use to store the output of the command. + Use last_task to depend on the last executed task. + Return the current task executed. + """ raise NotImplementedError def copy_file(self, id, local_path, remote_path, connection, last_task, vm=None): - """ Copy a file from local to remote. - Use last_task to depend on the last executed task. - Return the current task executed.""" + """Copy a file from local to remote. + Use last_task to depend on the last executed task. + Return the current task executed. + """ raise NotImplementedError - def remote_command(self, id, remote_command, connection, last_task, logger_name, output_callback=None): - """ Execute a command in the remote server. - Use last_task to depend on the last executed task. - logger_name is the name of the logger to use to store the output of the command. - output_callback is a function to be called with the output of the command. - Return the current task executed.""" + def remote_command( + self, id, remote_command, connection, last_task, logger_name, output_callback=None, populate_env=True + ): + """Execute a command in the remote server. + Use last_task to depend on the last executed task. + logger_name is the name of the logger to use to store the output of the command. + output_callback is a function to be called with the output of the command. + Return the current task executed. + """ raise NotImplementedError def remote_copy_folders( self, source_folder, destination_folder, command_id, connection, depends_on, relative_path=False, vm=None ): - """ The best option would be zip folder on local system and copy to remote machine - There is a weird behaviour synchronizing local command and remote command - Uggly workaround: Copy files and folder one by one :-( ) """ + """The best option would be zip folder on local system and copy to remote machine + There is a weird behaviour synchronizing local command and remote command + Uggly workaround: Copy files and folder one by one :-( ) + """ raise NotImplementedError(f"Copy folders not implemented") diff --git a/utils/virtual_machine/virtual_machine_provisioner.py b/utils/virtual_machine/virtual_machine_provisioner.py index 6b4eada9323..fff059f4661 100644 --- a/utils/virtual_machine/virtual_machine_provisioner.py +++ b/utils/virtual_machine/virtual_machine_provisioner.py @@ -2,15 +2,24 @@ import yaml from yamlinclude import YamlIncludeConstructor from utils.tools import logger +from utils.virtual_machine.utils import nginx_parser class VirtualMachineProvisioner: - """ Manages the provision parser for the virtual machines.""" + """Manages the provision parser for the virtual machines.""" def remove_unsupported_machines( - self, library_name, weblog, required_vms, vm_provider_id, vm_only_branch, vm_skip_branches + self, + library_name, + weblog, + required_vms, + vm_provider_id, + vm_only_branch, + vm_skip_branches, + only_default_vms, + vm_only, ): - """ Remove unsupported machines based on the provision file, weblog, provider_id and local testing parameter: vm_only_branch """ + """Remove unsupported machines based on the provision file, weblog, provider_id and local testing parameter: vm_only_branch""" weblog_provision_file = f"utils/build/virtual_machine/weblogs/{library_name}/provision_{weblog}.yml" config_data = None @@ -26,11 +35,22 @@ def remove_unsupported_machines( for vm in required_vms: installations = config_data["weblog"]["install"] allowed = False + if "exact_os_branches" in config_data["weblog"]: + if vm.os_branch not in config_data["weblog"]["exact_os_branches"]: + logger.stdout(f"WARNING: Removed VM [{vm.name}] due to weblog directive in exact_os_branches") + vms_to_remove.append(vm) + continue + # Exclude by vm_only_branch if vm_only_branch and vm.os_branch != vm_only_branch: logger.stdout(f"WARNING: Removed VM [{vm.name}] due to vm_only_branch directive") vms_to_remove.append(vm) continue + # Exclude by vm_only + if vm_only and vm.name != vm_only: + logger.stdout(f"WARNING: Removed VM [{vm.name}] due to vm_only directive") + vms_to_remove.append(vm) + continue # Exclude by vm_skip_branches if vm_skip_branches and vm.os_branch in skipped_branches: logger.stdout(f"WARNING: Removed VM [{vm.name}] due to vm_skip_branches directive") @@ -45,6 +65,13 @@ def remove_unsupported_machines( logger.stdout(f"WARNING: Removed VM [{vm.name}] due to weblog directive in excluded_os_branches") vms_to_remove.append(vm) continue + + # Exclude by excluded_os_names + if "excluded_os_names" in config_data["weblog"] and vm.name in config_data["weblog"]["excluded_os_names"]: + logger.stdout(f"WARNING: Removed VM [{vm.name}] due to weblog directive in excluded_os_names") + vms_to_remove.append(vm) + continue + # Exlude by vm_provider_id and vm configuration. IE: vm_provider_id: vagrant exclude all vms that don't have vagrant configuration if vm_provider_id == "vagrant" and vm.vagrant_config is None: logger.stdout(f"WARNING: Removed VM [{vm.name}] due to it's not a Vagrant VM") @@ -78,15 +105,24 @@ def remove_unsupported_machines( if allowed == False: logger.stdout(f"WARNING: Weblog doesn't support VM [{vm.name}]. Removed!") vms_to_remove.append(vm) + + if not vm_only_branch and only_default_vms != "All": + if only_default_vms == "True" and not vm.default_vm: + logger.stdout(f"WARNING: Removed VM [{vm.name}] due to it's not a default VM") + vms_to_remove.append(vm) + if only_default_vms == "False" and vm.default_vm: + logger.stdout(f"WARNING: Removed VM [{vm.name}] due to it's a default VM") + vms_to_remove.append(vm) # Ok remove the vms for vm in vms_to_remove: - required_vms.remove(vm) + if vm in required_vms: + required_vms.remove(vm) def get_provision(self, library_name, env, weblog, vm_provision_name, os_type, os_distro, os_branch, os_cpu): - """ Parse the provision files (main provision file and weblog provision file) and return a Provision object""" + """Parse the provision files (main provision file and weblog provision file) and return a Provision object""" YamlIncludeConstructor.add_to_loader_class(loader_class=yaml.FullLoader, base_dir=".") - provision = Provision() + provision = Provision(vm_provision_name) provision_file = f"utils/build/virtual_machine/provisions/{vm_provision_name}/provision.yml" weblog_provision_file = f"utils/build/virtual_machine/weblogs/{library_name}/provision_{weblog}.yml" @@ -112,6 +148,10 @@ def get_provision(self, library_name, env, weblog, vm_provision_name, os_type, o provision.tested_components_installation = self._get_tested_components( env, library_name, os_type, os_distro, os_branch, os_cpu, provsion_raw_data ) + # Load vm logs extractor installation + provision.vm_logs_installation = self._get_vm_logs( + env, library_name, os_type, os_distro, os_branch, os_cpu, provsion_raw_data + ) # Load lang variant installation if exists. Lang variant is denfined in the weblog provision file provision.lang_variant_installation = self._get_lang_variant_provision( env, library_name, os_type, os_distro, os_branch, os_cpu, weblog_raw_data @@ -146,6 +186,7 @@ def _get_provision_step( installation = self._get_installation(env, library_name, os_type, os_distro, os_branch, os_cpu, installations) installation.id = step_name installation.cache = provision_step["cache"] if "cache" in provision_step else False + installation.populate_env = provision_step["populate_env"] if "populate_env" in provision_step else True return installation def _get_tested_components(self, env, library_name, os_type, os_distro, os_branch, os_cpu, provsion_raw_data): @@ -156,15 +197,28 @@ def _get_tested_components(self, env, library_name, os_type, os_distro, os_branc installation.id = "tested_components" return installation + def _get_vm_logs(self, env, library_name, os_type, os_distro, os_branch, os_cpu, provsion_raw_data): + if "vm_logs" in provsion_raw_data: + tested_components = provsion_raw_data["vm_logs"] + installations = tested_components["install"] + installation = self._get_installation( + env, library_name, os_type, os_distro, os_branch, os_cpu, installations + ) + installation.id = "vm_logs" + return installation + return None + def _get_lang_variant_provision(self, env, library_name, os_type, os_distro, os_branch, os_cpu, weblog_raw_data): if "lang_variant" not in weblog_raw_data: - logger.debug(f"lang_variant not found in weblog provision file") + logger.debug("lang_variant not found in weblog provision file") return None lang_variant = weblog_raw_data["lang_variant"] installations = lang_variant["install"] installation = self._get_installation(env, library_name, os_type, os_distro, os_branch, os_cpu, installations) installation.id = lang_variant["name"] installation.cache = lang_variant["cache"] if "cache" in lang_variant else False + installation.populate_env = lang_variant["populate_env"] if "populate_env" in lang_variant else True + installation.version = lang_variant["version"] if "version" in lang_variant else None return installation def _get_weblog_provision( @@ -174,11 +228,25 @@ def _get_weblog_provision( weblog = weblog_raw_data["weblog"] assert weblog["name"] == weblog_name, f"Weblog name {weblog_name} does not match the provision file name" installations = weblog["install"] - installation = self._get_installation(env, library_name, os_type, os_distro, os_branch, os_cpu, installations) + ci_commit_branch = os.getenv("GITLAB_CI") + installation = self._get_installation( + env, + library_name, + os_type, + os_distro, + os_branch, + os_cpu, + installations, + use_git=ci_commit_branch is not None, + ) installation.id = weblog["name"] + installation.nginx_config = weblog["nginx_config"] if "nginx_config" in weblog else None + installation.version = weblog["runtime_version"] if "runtime_version" in weblog else None return installation - def _get_installation(self, env, library_name, os_type, os_distro, os_branch, os_cpu, installations_raw_data): + def _get_installation( + self, env, library_name, os_type, os_distro, os_branch, os_cpu, installations_raw_data, use_git=False + ): installation_raw_data = None for install in installations_raw_data: if "env" in install and install["env"] != env: @@ -207,47 +275,135 @@ def _get_installation(self, env, library_name, os_type, os_distro, os_branch, os installation.remote_command = ( installation_raw_data["remote-command"] if "remote-command" in installation_raw_data else None ) + if "copy_files" in installation_raw_data: for copy_file in installation_raw_data["copy_files"]: installation.copy_files.append( CopyFile( copy_file["name"], copy_file["remote_path"] if "remote_path" in copy_file else None, - copy_file["local_path"], + copy_file["local_path"] if "local_path" in copy_file and not use_git else None, + copy_file["local_path"] if "local_path" in copy_file and use_git else None, ) ) return installation +class _DeployedWeblog: + def __init__(self, weblog_name, runtime_version=None, app_type=None, app_context_url="/") -> None: + self.weblog_name = weblog_name + self.runtime_version = runtime_version + self.app_type = app_type + self.app_context_url = app_context_url + # The weblog is deployed as a multicontainer app + self.multicontainer_apps = [] + + class Provision: - """ Contains all the information about the provision that it will be launched on the vm 1""" + """Contains all the information about the provision that it will be launched on the vm 1""" - def __init__(self): + def __init__(self, provision_name): + self.provision_name = provision_name self.env = {} self.installations = [] self.lang_variant_installation = None self.weblog_installation = None self.tested_components_installation = None + self.vm_logs_installation = None + self.deployed_weblog = None + + def get_deployed_weblog(self): + """Usually we have only one weblog deployed in the VM. But in some cases(multicontainer) we can have multiple weblogs deployed.""" + if not self.deployed_weblog: + # App on Container/Alpine + if self.weblog_installation and self.weblog_installation.version: + self.deployed_weblog = _DeployedWeblog( + weblog_name=self.weblog_installation.id, + runtime_version=str(self.weblog_installation.version), + app_type="container" if "container" in self.weblog_installation.id else "alpine", + app_context_url="/", + ) + + # Multicontainer app + elif self.weblog_installation and self.weblog_installation.nginx_config: + # Define the main weblog as multicontainer + self.deployed_weblog = _DeployedWeblog( + weblog_name=self.weblog_installation.id, + runtime_version=None, + app_type="multicontainer", + app_context_url="/", + ) + # Now add the multicontainer apps + apps_json = nginx_parser(self.weblog_installation.nginx_config) + logger.debug(f"Multicontainer/multialpine apps definition: {apps_json}") + + for app in apps_json: + self.deployed_weblog.multicontainer_apps.append( + _DeployedWeblog( + weblog_name=self.weblog_installation.id, + runtime_version=str(app["runtime"]), + app_type=app["type"], + app_context_url=app["url"], + ) + ) + # App on Host + elif self.lang_variant_installation and self.lang_variant_installation.version: + self.deployed_weblog = _DeployedWeblog( + weblog_name=self.weblog_installation.id, + runtime_version=str(self.lang_variant_installation.version), + app_type="host", + app_context_url="/", + ) + + return self.deployed_weblog class Intallation: - """ Generic installation object. It can be a installation, lang_variant installation or weblog installation.""" + """Generic installation object. It can be a installation, lang_variant installation or weblog installation.""" def __init__(self): self.id = False self.cache = False + self.populate_env = True self.local_command = None self.local_script = None self.remote_command = None + self.version = None + self.nginx_config = None self.copy_files = [] + def __repr__(self): + """We use this method to calculate the hash of the object (cache)""" + return ( + self.id + + "_" + + (self.local_command or "") + + "_" + + (self.remote_command or "") + + "_" + + (self.local_script or "") + + "_" + + repr(self.copy_files) + ) + class CopyFile: - def __init__(self, name, remote_path, local_path): + def __init__(self, name, remote_path, local_path, git_path): self.remote_path = remote_path self.local_path = local_path + self.git_path = git_path self.name = name + def __repr__(self): + """We use this method to calculate the hash of the object (cache)""" + return ( + (self.remote_path or "") + + "_" + + (self.git_path if self.git_path else self.local_path or "") + + "_" + + self.name + ) + provisioner = VirtualMachineProvisioner() diff --git a/utils/virtual_machine/vm_logger.py b/utils/virtual_machine/vm_logger.py index e584f6e2179..a5ad1efb6ac 100644 --- a/utils/virtual_machine/vm_logger.py +++ b/utils/virtual_machine/vm_logger.py @@ -1,12 +1,13 @@ import logging import logging.config +from utils import context def vm_logger(scenario_name, log_name, level=logging.INFO): specified_logger = logging.getLogger(log_name) if len(specified_logger.handlers) == 0: - formatter = logging.Formatter("%(message)s") - handler = logging.FileHandler(f"logs_{scenario_name.lower()}/{log_name}.log") + formatter = logging.Formatter("%(asctime)s:%(message)s", "%Y-%m-%d %H.%M.%S") + handler = logging.FileHandler(f"{context.scenario.host_log_folder}/{log_name}.log") handler.setFormatter(formatter) specified_logger.setLevel(level) specified_logger.addHandler(handler)